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/pc98/pc98/pcaudio.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 /*-
    2  * Copyright (c) 1994-1998 Sen Schmidt
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer,
   10  *    without modification, immediately at the beginning of the file.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * $FreeBSD: releng/5.0/sys/pc98/pc98/pcaudio.c 104676 2002-10-08 12:54:56Z nyan $
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/conf.h>
   34 #include <sys/proc.h>
   35 #include <sys/kernel.h>
   36 #include <sys/bus.h>
   37 #include <sys/filio.h>
   38 #include <sys/poll.h>
   39 #include <sys/vnode.h>
   40 
   41 #include <machine/clock.h>
   42 #include <machine/pcaudioio.h>
   43 
   44 #ifdef PC98
   45 #include <pc98/pc98/pc98.h>
   46 #else
   47 #include <isa/isareg.h>
   48 #endif
   49 #include <isa/isavar.h>
   50 #include <i386/isa/timerreg.h>
   51 
   52 #define BUF_SIZE        8192
   53 #define SAMPLE_RATE     8000
   54 #define INTERRUPT_RATE  16000
   55 
   56 static struct pca_status {
   57         char            open;           /* device open */
   58         char            queries;        /* did others try opening */
   59         unsigned char   *buf[3];        /* triple buffering */
   60         unsigned char   *buffer;        /* current buffer ptr */
   61         unsigned        in_use[3];      /* buffers fill */
   62         unsigned        index;          /* index in current buffer */
   63         unsigned        counter;        /* sample counter */
   64         unsigned        scale;          /* sample counter scale */
   65         unsigned        sample_rate;    /* sample rate */
   66         unsigned        processed;      /* samples processed */
   67         unsigned        volume;         /* volume for pc-speaker */
   68         char            encoding;       /* Ulaw, Alaw or linear */
   69         u_char          current;        /* current buffer */
   70         unsigned char   oldval;         /* old timer port value */
   71         char            timer_on;       /* is playback running */
   72         struct selinfo  wsel;           /* select/poll status */
   73 } pca_status;
   74 
   75 static char buffer1[BUF_SIZE];
   76 static char buffer2[BUF_SIZE];
   77 static char buffer3[BUF_SIZE];
   78 static char volume_table[256];
   79 
   80 static unsigned char ulaw_dsp[] = {
   81      3,    7,   11,   15,   19,   23,   27,   31,
   82     35,   39,   43,   47,   51,   55,   59,   63,
   83     66,   68,   70,   72,   74,   76,   78,   80,
   84     82,   84,   86,   88,   90,   92,   94,   96,
   85     98,   99,  100,  101,  102,  103,  104,  105,
   86    106,  107,  108,  109,  110,  111,  112,  113,
   87    113,  114,  114,  115,  115,  116,  116,  117,
   88    117,  118,  118,  119,  119,  120,  120,  121,
   89    121,  121,  122,  122,  122,  122,  123,  123,
   90    123,  123,  124,  124,  124,  124,  125,  125,
   91    125,  125,  125,  125,  126,  126,  126,  126,
   92    126,  126,  126,  126,  127,  127,  127,  127,
   93    127,  127,  127,  127,  127,  127,  127,  127,
   94    128,  128,  128,  128,  128,  128,  128,  128,
   95    128,  128,  128,  128,  128,  128,  128,  128,
   96    128,  128,  128,  128,  128,  128,  128,  128,
   97    253,  249,  245,  241,  237,  233,  229,  225,
   98    221,  217,  213,  209,  205,  201,  197,  193,
   99    190,  188,  186,  184,  182,  180,  178,  176,
  100    174,  172,  170,  168,  166,  164,  162,  160,
  101    158,  157,  156,  155,  154,  153,  152,  151,
  102    150,  149,  148,  147,  146,  145,  144,  143,
  103    143,  142,  142,  141,  141,  140,  140,  139,
  104    139,  138,  138,  137,  137,  136,  136,  135,
  105    135,  135,  134,  134,  134,  134,  133,  133,
  106    133,  133,  132,  132,  132,  132,  131,  131,
  107    131,  131,  131,  131,  130,  130,  130,  130,
  108    130,  130,  130,  130,  129,  129,  129,  129,
  109    129,  129,  129,  129,  129,  129,  129,  129,
  110    128,  128,  128,  128,  128,  128,  128,  128,
  111    128,  128,  128,  128,  128,  128,  128,  128,
  112    128,  128,  128,  128,  128,  128,  128,  128,
  113 };
  114 
  115 static unsigned char alaw_linear[] = {
  116         45,     214,    122,    133,    0,              255,    107,    149, 
  117         86,     171,    126,    129,    0,              255,    117,    138, 
  118         13,     246,    120,    135,    0,              255,    99,     157, 
  119         70,     187,    124,    131,    0,              255,    113,    142, 
  120         61,     198,    123,    132,    0,              255,    111,    145, 
  121         94,     163,    127,    128,    0,              255,    119,    136, 
  122         29,     230,    121,    134,    0,              255,    103,    153, 
  123         78,     179,    125,    130,    0,              255,    115,    140, 
  124         37,     222,    122,    133,    0,              255,    105,    151, 
  125         82,     175,    126,    129,    0,              255,    116,    139, 
  126         5,      254,    120,    135,    0,              255,    97,     159, 
  127         66,     191,    124,    131,    0,              255,    112,    143, 
  128         53,     206,    123,    132,    0,              255,    109,    147, 
  129         90,     167,    127,    128,    0,              255,    118,    137, 
  130         21,     238,    121,    134,    0,              255,    101,    155, 
  131         74,     183,    125,    130,    0,              255,    114,    141, 
  132         49,     210,    123,    133,    0,              255,    108,    148, 
  133         88,     169,    127,    129,    0,              255,    118,    138, 
  134         17,     242,    121,    135,    0,              255,    100,    156, 
  135         72,     185,    125,    131,    0,              255,    114,    142, 
  136         64,     194,    124,    132,    0,              255,    112,    144, 
  137         96,     161,    128,    128,    1,              255,    120,    136, 
  138         33,     226,    122,    134,    0,              255,    104,    152, 
  139         80,     177,    126,    130,    0,              255,    116,    140, 
  140         41,     218,    122,    133,    0,              255,    106,    150, 
  141         84,     173,    126,    129,    0,              255,    117,    139, 
  142         9,      250,    120,    135,    0,              255,    98,     158, 
  143         68,     189,    124,    131,    0,              255,    113,    143, 
  144         57,     202,    123,    132,    0,              255,    110,    146, 
  145         92,     165,    127,    128,    0,              255,    119,    137, 
  146         25,     234,    121,    134,    0,              255,    102,    154, 
  147         76,     181,    125,    130,    0,              255,    115,    141, 
  148 };
  149 
  150 static int pca_sleep = 0;
  151 
  152 static void pcaintr(struct clockframe *frame);
  153 
  154 static  d_open_t        pcaopen;
  155 static  d_close_t       pcaclose;
  156 static  d_write_t       pcawrite;
  157 static  d_ioctl_t       pcaioctl;
  158 static  d_poll_t        pcapoll;
  159 
  160 #define CDEV_MAJOR 24
  161 static struct cdevsw pca_cdevsw = {
  162         /* open */      pcaopen,
  163         /* close */     pcaclose,
  164         /* read */      noread,
  165         /* write */     pcawrite,
  166         /* ioctl */     pcaioctl,
  167         /* poll */      pcapoll,
  168         /* mmap */      nommap,
  169         /* strategy */  nostrategy,
  170         /* name */      "pca",
  171         /* maj */       CDEV_MAJOR,
  172         /* dump */      nodump,
  173         /* psize */     nopsize,
  174         /* flags */     0,
  175 };
  176 
  177 static void pca_continue(void);
  178 static void pca_init(void);
  179 static void pca_pause(void);
  180 
  181 static void
  182 conv(const unsigned char *table, unsigned char *buff, unsigned n)
  183 {
  184         unsigned i;
  185 
  186         for (i = 0; i < n; i++)
  187                 buff[i] = table[buff[i]];
  188 }
  189 
  190 
  191 static void
  192 pca_volume(int volume)
  193 {
  194         int i, j;
  195 
  196         for (i=0; i<256; i++) {
  197                 j = ((i-128)*volume)/25;
  198 /* XXX
  199                 j = ((i-128)*volume)/100;
  200 */
  201                 if (j<-128)
  202                         j = -128;
  203                 if (j>127)
  204                         j = 127;
  205                 volume_table[i] = (((255-(j + 128))/4)+1);
  206         }
  207 }
  208 
  209 
  210 static void
  211 pca_init(void)
  212 {
  213         pca_status.open = 0;
  214         pca_status.queries = 0;
  215         pca_status.timer_on = 0;
  216         pca_status.buf[0] = (unsigned char *)&buffer1[0];
  217         pca_status.buf[1] = (unsigned char *)&buffer2[0];
  218         pca_status.buf[2] = (unsigned char *)&buffer3[0];
  219         pca_status.buffer = pca_status.buf[0];
  220         pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[2] = 0;
  221         pca_status.current = 0;
  222         pca_status.sample_rate = SAMPLE_RATE;
  223         pca_status.scale = (pca_status.sample_rate << 8) / INTERRUPT_RATE;
  224         pca_status.encoding = AUDIO_ENCODING_ULAW;
  225         pca_status.volume = 100;
  226 
  227         pca_volume(pca_status.volume);
  228 }
  229 
  230 
  231 static int
  232 pca_start(void)
  233 {
  234         int x = splhigh();
  235         int rv = 0;
  236 
  237         /* use the first buffer */
  238         pca_status.current  = 0;
  239         pca_status.index = 0;
  240         pca_status.counter = 0;
  241         pca_status.buffer  = pca_status.buf[pca_status.current];
  242 #ifdef PC98
  243         pca_status.oldval = inb(IO_PPI) & ~0x08;
  244 #else
  245         pca_status.oldval = inb(IO_PPI) | 0x03;
  246 #endif
  247         /* acquire the timers */
  248 #ifdef PC98
  249         if (acquire_timer1(TIMER_LSB|TIMER_ONESHOT))
  250 #else
  251         if (acquire_timer2(TIMER_LSB|TIMER_ONESHOT))
  252 #endif
  253                 rv = -1;
  254         else if (acquire_timer0(INTERRUPT_RATE, pcaintr)) {
  255 #ifdef PC98
  256                 release_timer1();
  257 #else
  258                 release_timer2();
  259 #endif
  260                 rv =  -1;
  261         } else
  262                 pca_status.timer_on = 1;
  263 
  264         splx(x);
  265         return rv;
  266 }
  267 
  268 
  269 static void
  270 pca_stop(void)
  271 {
  272         int x = splhigh();
  273 
  274         /* release the timers */
  275         release_timer0();
  276 #ifdef PC98
  277         release_timer1();
  278 #else
  279         release_timer2();
  280 #endif
  281         /* reset the buffer */
  282         pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[2] = 0;
  283         pca_status.index = 0;
  284         pca_status.counter = 0;
  285         pca_status.current = 0;
  286         pca_status.buffer = pca_status.buf[pca_status.current];
  287         pca_status.timer_on = 0;
  288         splx(x);
  289 }
  290 
  291 
  292 static void
  293 pca_pause(void)
  294 {
  295         int x = splhigh();
  296 
  297         release_timer0();
  298 #ifdef PC98
  299         release_timer1();
  300 #else
  301         release_timer2();
  302 #endif
  303         pca_status.timer_on = 0;
  304         splx(x);
  305 }
  306 
  307 
  308 static void
  309 pca_continue(void)
  310 {
  311         int x = splhigh();
  312 
  313 #ifdef PC98
  314         pca_status.oldval = inb(IO_PPI) & ~0x08;
  315         acquire_timer1(TIMER_LSB|TIMER_ONESHOT);
  316 #else
  317         pca_status.oldval = inb(IO_PPI) | 0x03;
  318         acquire_timer2(TIMER_LSB|TIMER_ONESHOT);
  319 #endif
  320         acquire_timer0(INTERRUPT_RATE, pcaintr);
  321         pca_status.timer_on = 1;
  322         splx(x);
  323 }
  324 
  325 
  326 static int
  327 pca_wait(void)
  328 {
  329         int error, x;
  330 
  331         if (!pca_status.timer_on)
  332                 return 0;
  333 
  334         while (pca_status.in_use[0] || pca_status.in_use[1] ||
  335             pca_status.in_use[2]) {
  336                 x = spltty();
  337                 pca_sleep = 1;
  338                 error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_drain", 0);
  339                 pca_sleep = 0;
  340                 splx(x);
  341                 if (error != 0 && error != ERESTART) {
  342                         pca_stop();
  343                         return error;
  344                 }
  345         }
  346         return 0;
  347 }
  348 
  349 
  350 static struct isa_pnp_id pca_ids[] = {
  351         {0x0008d041, "AT-style speaker sound"}, /* PNP0800 */
  352         {0}
  353 };
  354 
  355 static int
  356 pcaprobe(device_t dev)
  357 {
  358         /* Check isapnp ids */
  359         return ISA_PNP_PROBE(device_get_parent(dev), dev, pca_ids);
  360 }
  361 
  362 
  363 static int
  364 pcaattach(device_t dev)
  365 {
  366         pca_init();
  367         make_dev(&pca_cdevsw, 0, 0, 0, 0600, "pcaudio");
  368         make_dev(&pca_cdevsw, 128, 0, 0, 0600, "pcaudioctl");
  369         return 0;
  370 }
  371 
  372 static device_method_t pca_methods[] = {
  373         DEVMETHOD(device_probe,         pcaprobe),
  374         DEVMETHOD(device_attach,        pcaattach),
  375         { 0, 0 }
  376 };
  377 
  378 static driver_t pca_driver = {
  379         "pca",
  380         pca_methods,
  381         1
  382 };
  383 
  384 static devclass_t pca_devclass;
  385 
  386 DRIVER_MODULE(pca, isa, pca_driver, pca_devclass, 0, 0);
  387 
  388 
  389 static int
  390 pcaopen(dev_t dev, int flags, int fmt, struct thread *td)
  391 {
  392         /* audioctl device can always be opened */
  393         if (minor(dev) == 128)
  394                 return 0;
  395         if (minor(dev) > 0)
  396                 return ENXIO;
  397 
  398         /* audio device can only be open by one process */
  399         if (pca_status.open) {
  400                 pca_status.queries = 1;
  401                 return EBUSY;
  402         }
  403         pca_status.buffer = pca_status.buf[0];
  404         pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[2] = 0;
  405         pca_status.timer_on = 0;
  406         pca_status.open = 1;
  407         pca_status.processed = 0;
  408         return 0;
  409 }
  410 
  411 
  412 static int
  413 pcaclose(dev_t dev, int flags, int fmt, struct thread *td)
  414 {
  415         /* audioctl device can always be closed */
  416         if (minor(dev) == 128)
  417                 return 0;
  418         if (minor(dev) > 0)
  419                 return ENXIO;
  420         /* audio device close drains all output and restores timers */
  421         pca_wait();
  422         pca_stop();
  423         pca_status.open = 0;
  424         return 0;
  425 }
  426 
  427 
  428 static int
  429 pcawrite(dev_t dev, struct uio *uio, int flag)
  430 {
  431         int count, error, which, x;
  432 
  433         /* only audio device can be written */
  434         if (minor(dev) > 0)
  435                 return ENXIO;
  436 
  437         while ((count = min(BUF_SIZE, uio->uio_resid)) > 0) {
  438                 if (pca_status.in_use[0] && pca_status.in_use[1] &&
  439                     pca_status.in_use[2]) {
  440                         if (flag & IO_NDELAY)
  441                                 return EWOULDBLOCK;
  442                         x = spltty();
  443                         pca_sleep = 1;
  444                         error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_wait", 0);
  445                         pca_sleep = 0;
  446                         splx(x);
  447                         if (error != 0 && error != ERESTART) {
  448                                 pca_stop();
  449                                 return error;
  450                         }
  451                 }
  452                 if (!pca_status.in_use[0])
  453                         which = 0;
  454                 else if (!pca_status.in_use[1])
  455                         which = 1;
  456                 else
  457                         which = 2;
  458                 if (count && !pca_status.in_use[which]) {
  459                         uiomove(pca_status.buf[which], count, uio);
  460                         pca_status.processed += count;
  461                         switch (pca_status.encoding) {
  462                         case AUDIO_ENCODING_ULAW:
  463                                 conv(ulaw_dsp, pca_status.buf[which], count);
  464                                 break;
  465 
  466                         case AUDIO_ENCODING_ALAW:
  467                                 conv(alaw_linear, pca_status.buf[which], count);
  468                                 break;
  469 
  470                         case AUDIO_ENCODING_RAW:
  471                                 break;
  472                         }
  473                         pca_status.in_use[which] = count;
  474                         if (!pca_status.timer_on)
  475                                 if (pca_start())
  476                                         return EBUSY;
  477                 }
  478         }
  479         return 0;
  480 }
  481 
  482 
  483 static int
  484 pcaioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
  485 {
  486         audio_info_t *auptr;
  487 
  488         switch(cmd) {
  489 
  490         case AUDIO_GETINFO:
  491                 auptr = (audio_info_t *)data;
  492                 auptr->play.sample_rate = pca_status.sample_rate;
  493                 auptr->play.channels = 1;
  494                 auptr->play.precision = 8;
  495                 auptr->play.encoding = pca_status.encoding;
  496 
  497                 auptr->play.gain = pca_status.volume;
  498                 auptr->play.port = 0;
  499 
  500                 auptr->play.samples = pca_status.processed;
  501                 auptr->play.eof = 0;
  502                 auptr->play.pause = !pca_status.timer_on;
  503                 auptr->play.error = 0;
  504                 auptr->play.waiting = pca_status.queries;
  505 
  506                 auptr->play.open = pca_status.open;
  507                 auptr->play.active = pca_status.timer_on;
  508                 return 0;
  509 
  510         case AUDIO_SETINFO:
  511                 auptr = (audio_info_t *)data;
  512                 if (auptr->play.sample_rate != (unsigned int)~0) {
  513                         pca_status.sample_rate = auptr->play.sample_rate;
  514                         pca_status.scale =
  515                                 (pca_status.sample_rate << 8) / INTERRUPT_RATE;
  516                 }
  517                 if (auptr->play.encoding != (unsigned int)~0) {
  518                         pca_status.encoding = auptr->play.encoding;
  519                 }
  520                 if (auptr->play.gain != (unsigned int)~0) {
  521                         pca_status.volume = auptr->play.gain;
  522                         pca_volume(pca_status.volume);
  523                 }
  524                 if (auptr->play.pause != (unsigned char)~0) {
  525                         if (auptr->play.pause)
  526                                 pca_pause();
  527                         else
  528                                 pca_continue();
  529                 }
  530 
  531                 return 0;
  532 
  533         case AUDIO_DRAIN:
  534         case AUDIO_COMPAT_DRAIN:
  535                 return pca_wait();
  536 
  537         case AUDIO_FLUSH:
  538         case AUDIO_COMPAT_FLUSH:
  539                 pca_stop();
  540                 return 0;
  541         case FIONBIO:
  542                 return 0;
  543         }
  544         return ENXIO;
  545 }
  546 
  547 
  548 static void
  549 pcaintr(struct clockframe *frame)
  550 {
  551         if (pca_status.index < pca_status.in_use[pca_status.current]) {
  552                 disable_intr();
  553 #ifdef PC98
  554                 __asm__("outb %0,$0x35\n"
  555                         "orb $0x08,%0\n"
  556                         "outb %0,$0x35"
  557 #else
  558                 __asm__("outb %0,$0x61\n"
  559                         "andb $0xFE,%0\n"
  560                         "outb %0,$0x61"
  561 #endif
  562                         : : "a" ((char)pca_status.oldval) );
  563                 __asm__("xlatb\n"
  564 #ifdef PC98
  565                         "outb %0,%%dx"
  566                         : : "a" ((char)pca_status.buffer[pca_status.index]),
  567                             "b" (volume_table),
  568                             "d" ((u_short)0x3fdb) );
  569 #else
  570                         "outb %0,$0x42"
  571                         : : "a" ((char)pca_status.buffer[pca_status.index]),
  572                             "b" (volume_table) );
  573 #endif
  574                 enable_intr();
  575                 pca_status.counter += pca_status.scale;
  576                 pca_status.index = (pca_status.counter >> 8);
  577         }
  578         if (pca_status.index >= pca_status.in_use[pca_status.current]) {
  579                 pca_status.index = pca_status.counter = 0;
  580                 pca_status.in_use[pca_status.current] = 0;
  581                 pca_status.current++;
  582                 if (pca_status.current > 2)
  583                         pca_status.current = 0;
  584                 pca_status.buffer = pca_status.buf[pca_status.current];
  585                 if (pca_sleep)
  586                         wakeup(&pca_sleep);
  587                 if (SEL_WAITING(&pca_status.wsel))
  588                         selwakeup(&pca_status.wsel);
  589         }
  590 }
  591 
  592 
  593 static int
  594 pcapoll(dev_t dev, int events, struct thread *td)
  595 {
  596         int s;
  597         int revents = 0;
  598 
  599         s = spltty();
  600 
  601         if (events & (POLLOUT | POLLWRNORM)) {
  602                 if (!pca_status.in_use[0] || !pca_status.in_use[1] ||
  603                     !pca_status.in_use[2])
  604                         revents |= events & (POLLOUT | POLLWRNORM);
  605                 else
  606                         selrecord(td, &pca_status.wsel);
  607         }
  608         splx(s);
  609         return (revents);
  610 }

Cache object: 5c1bd05953b2ef6b76b5cdf5a95259b3


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