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/sound/pcm/sound.h

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
    3  * Copyright by Hannu Savolainen 1995
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   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  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD$
   28  */
   29 
   30 /*
   31  * first, include kernel header files.
   32  */
   33 
   34 #ifndef _OS_H_
   35 #define _OS_H_
   36 
   37 #ifdef _KERNEL
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/ioccom.h>
   41 #include <sys/filio.h>
   42 #include <sys/sockio.h>
   43 #include <sys/fcntl.h>
   44 #include <sys/tty.h>
   45 #include <sys/proc.h>
   46 #include <sys/kernel.h> /* for DATA_SET */
   47 #include <sys/module.h>
   48 #include <sys/conf.h>
   49 #include <sys/file.h>
   50 #include <sys/uio.h>
   51 #include <sys/syslog.h>
   52 #include <sys/errno.h>
   53 #include <sys/malloc.h>
   54 #include <sys/bus.h>
   55 #if __FreeBSD_version < 500000
   56 #include <sys/buf.h>
   57 #endif
   58 #include <machine/resource.h>
   59 #include <machine/bus.h>
   60 #include <sys/rman.h>
   61 #include <sys/limits.h>
   62 #include <sys/mman.h>
   63 #include <sys/poll.h>
   64 #include <sys/sbuf.h>
   65 #include <sys/soundcard.h>
   66 #include <sys/sysctl.h>
   67 #include <sys/kobj.h>
   68 #include <vm/vm.h>
   69 #include <vm/pmap.h>
   70 
   71 #undef  USING_MUTEX
   72 #undef  USING_DEVFS
   73 
   74 #if __FreeBSD_version > 500000
   75 #include <sys/lock.h>
   76 #include <sys/mutex.h>
   77 #include <sys/condvar.h>
   78 
   79 #define USING_MUTEX
   80 #define USING_DEVFS
   81 #else
   82 #define INTR_TYPE_AV    INTR_TYPE_TTY
   83 #define INTR_MPSAFE     0
   84 #endif
   85 
   86 #define SND_DYNSYSCTL
   87 
   88 struct pcm_channel;
   89 struct pcm_feeder;
   90 struct snd_dbuf;
   91 struct snd_mixer;
   92 
   93 #include <dev/sound/pcm/buffer.h>
   94 #include <dev/sound/pcm/channel.h>
   95 #include <dev/sound/pcm/feeder.h>
   96 #include <dev/sound/pcm/mixer.h>
   97 #include <dev/sound/pcm/dsp.h>
   98 #include <dev/sound/clone.h>
   99 #include <dev/sound/unit.h>
  100 
  101 #define PCM_SOFTC_SIZE  512
  102 
  103 #define SND_STATUSLEN   64
  104 
  105 #define SOUND_MODVER    2
  106 
  107 #define SOUND_MINVER    SOUND_MODVER
  108 #define SOUND_PREFVER   SOUND_MODVER
  109 #define SOUND_MAXVER    SOUND_MODVER
  110 
  111 /*
  112  * We're abusing the fact that MAXMINOR still have enough room
  113  * for our bit twiddling and nobody ever need 512 unique soundcards,
  114  * 32 unique device types and 1024 unique cloneable devices for the
  115  * next 100 years...
  116  */
  117 
  118 #define PCMMAXUNIT              (snd_max_u())
  119 #define PCMMAXDEV               (snd_max_d())
  120 #define PCMMAXCHAN              (snd_max_c())
  121 
  122 #define PCMMAXCLONE             PCMMAXCHAN
  123 
  124 #define PCMUNIT(x)              (snd_unit2u(dev2unit(x)))
  125 #define PCMDEV(x)               (snd_unit2d(dev2unit(x)))
  126 #define PCMCHAN(x)              (snd_unit2c(dev2unit(x)))
  127 
  128 /*
  129  * By design, limit possible channels for each direction.
  130  */
  131 #define SND_MAXHWCHAN           256
  132 #define SND_MAXVCHANS           SND_MAXHWCHAN
  133 
  134 #define SD_F_SIMPLEX            0x00000001
  135 #define SD_F_AUTOVCHAN          0x00000002
  136 #define SD_F_SOFTPCMVOL         0x00000004
  137 #define SD_F_PSWAPLR            0x00000008
  138 #define SD_F_RSWAPLR            0x00000010
  139 #define SD_F_DYING              0x00000020
  140 #define SD_F_SUICIDE            0x00000040
  141 #define SD_F_BUSY               0x00000080
  142 #define SD_F_MPSAFE             0x00000100
  143 #define SD_F_REGISTERED         0x00000200
  144 
  145 #define SD_F_PRIO_RD            0x10000000
  146 #define SD_F_PRIO_WR            0x20000000
  147 #define SD_F_PRIO_SET           (SD_F_PRIO_RD | SD_F_PRIO_WR)
  148 #define SD_F_DIR_SET            0x40000000
  149 #define SD_F_TRANSIENT          0xf0000000
  150 
  151 #define PCM_ALIVE(x)            ((x) != NULL && (x)->lock != NULL &&    \
  152                                  !((x)->flags & SD_F_DYING))
  153 #define PCM_REGISTERED(x)       (PCM_ALIVE(x) &&                        \
  154                                  ((x)->flags & SD_F_REGISTERED))
  155 
  156 /* many variables should be reduced to a range. Here define a macro */
  157 #define RANGE(var, low, high) (var) = \
  158         (((var)<(low))? (low) : ((var)>(high))? (high) : (var))
  159 #define DSP_BUFFSIZE (8192)
  160 
  161 /*
  162  * Macros for reading/writing PCM sample / int values from bytes array.
  163  * Since every process is done using signed integer (and to make our life
  164  * less miserable), unsigned sample will be converted to its signed
  165  * counterpart and restored during writing back. To avoid overflow,
  166  * we truncate 32bit (and only 32bit) samples down to 24bit (see below
  167  * for the reason), unless PCM_USE_64BIT_ARITH is defined.
  168  */
  169 
  170 /*
  171  * Automatically turn on 64bit arithmetic on suitable archs
  172  * (amd64 64bit, ia64, etc..) for wider 32bit samples / integer processing.
  173  */
  174 #if LONG_BIT >= 64
  175 #undef PCM_USE_64BIT_ARITH
  176 #define PCM_USE_64BIT_ARITH     1
  177 #else
  178 #if 0
  179 #undef PCM_USE_64BIT_ARITH
  180 #define PCM_USE_64BIT_ARITH     1
  181 #endif
  182 #endif
  183 
  184 #ifdef PCM_USE_64BIT_ARITH
  185 typedef int64_t intpcm_t;
  186 #else
  187 typedef int32_t intpcm_t;
  188 #endif
  189 
  190 /* 32bit fixed point shift */
  191 #define PCM_FXSHIFT     8
  192 
  193 #define PCM_S8_MAX        0x7f
  194 #define PCM_S8_MIN       -0x80
  195 #define PCM_S16_MAX       0x7fff
  196 #define PCM_S16_MIN      -0x8000
  197 #define PCM_S24_MAX       0x7fffff
  198 #define PCM_S24_MIN      -0x800000
  199 #ifdef PCM_USE_64BIT_ARITH
  200 #if LONG_BIT >= 64
  201 #define PCM_S32_MAX       0x7fffffffL
  202 #define PCM_S32_MIN      -0x80000000L
  203 #else
  204 #define PCM_S32_MAX       0x7fffffffLL
  205 #define PCM_S32_MIN      -0x80000000LL
  206 #endif
  207 #else
  208 #define PCM_S32_MAX       0x7fffffff
  209 #define PCM_S32_MIN     (-0x7fffffff - 1)
  210 #endif
  211 
  212 /* Bytes-per-sample definition */
  213 #define PCM_8_BPS       1
  214 #define PCM_16_BPS      2
  215 #define PCM_24_BPS      3
  216 #define PCM_32_BPS      4
  217 
  218 #if BYTE_ORDER == LITTLE_ENDIAN
  219 #define PCM_READ_S16_LE(b8)             *((int16_t *)(b8))
  220 #define _PCM_READ_S32_LE(b8)            *((int32_t *)(b8))
  221 #define PCM_READ_S16_BE(b8) \
  222                 ((int32_t)((b8)[1] | ((int8_t)((b8)[0])) << 8))
  223 #define _PCM_READ_S32_BE(b8) \
  224                 ((int32_t)((b8)[3] | (b8)[2] << 8 | (b8)[1] << 16 | \
  225                         ((int8_t)((b8)[0])) << 24))
  226 
  227 #define PCM_WRITE_S16_LE(b8, val)       *((int16_t *)(b8)) = (val)
  228 #define _PCM_WRITE_S32_LE(b8, val)      *((int32_t *)(b8)) = (val)
  229 #define PCM_WRITE_S16_BE(bb8, vval) do { \
  230                         int32_t val = (vval); \
  231                         uint8_t *b8 = (bb8); \
  232                         b8[1] = val; \
  233                         b8[0] = val >> 8; \
  234                 } while(0)
  235 #define _PCM_WRITE_S32_BE(bb8, vval) do { \
  236                         int32_t val = (vval); \
  237                         uint8_t *b8 = (bb8); \
  238                         b8[3] = val; \
  239                         b8[2] = val >> 8; \
  240                         b8[1] = val >> 16; \
  241                         b8[0] = val >> 24; \
  242                 } while(0)
  243 
  244 #define PCM_READ_U16_LE(b8)             ((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
  245 #define _PCM_READ_U32_LE(b8)            ((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
  246 #define PCM_READ_U16_BE(b8) \
  247                 ((int32_t)((b8)[1] | ((int8_t)((b8)[0] ^ 0x80)) << 8))
  248 #define _PCM_READ_U32_BE(b8) \
  249                 ((int32_t)((b8)[3] | (b8)[2] << 8 | (b8)[1] << 16 | \
  250                         ((int8_t)((b8)[0] ^ 0x80)) << 24))
  251 
  252 #define PCM_WRITE_U16_LE(b8, val)       *((uint16_t *)(b8)) = (val) ^ 0x8000
  253 #define _PCM_WRITE_U32_LE(b8, val)      *((uint32_t *)(b8)) = (val) ^ 0x80000000
  254 #define PCM_WRITE_U16_BE(bb8, vval) do { \
  255                         int32_t val = (vval); \
  256                         uint8_t *b8 = (bb8); \
  257                         b8[1] = val; \
  258                         b8[0] = (val >> 8) ^ 0x80; \
  259                 } while(0)
  260 #define _PCM_WRITE_U32_BE(bb8, vval) do { \
  261                         int32_t val = (vval); \
  262                         uint8_t *b8 = (bb8); \
  263                         b8[3] = val; \
  264                         b8[2] = val >> 8; \
  265                         b8[1] = val >> 16; \
  266                         b8[0] = (val >> 24) ^ 0x80; \
  267                 } while(0)
  268 #else /* !LITTLE_ENDIAN */
  269 #define PCM_READ_S16_LE(b8) \
  270                 ((int32_t)((b8)[0] | ((int8_t)((b8)[1])) << 8))
  271 #define _PCM_READ_S32_LE(b8) \
  272                 ((int32_t)((b8)[0] | (b8)[1] << 8 | (b8)[2] << 16 | \
  273                         ((int8_t)((b8)[3])) << 24))
  274 #define PCM_READ_S16_BE(b8)             *((int16_t *)(b8))
  275 #define _PCM_READ_S32_BE(b8)            *((int32_t *)(b8))
  276 
  277 #define PCM_WRITE_S16_LE(bb8, vval) do { \
  278                         int32_t val = (vval); \
  279                         uint8_t *b8 = (bb8); \
  280                         b8[0] = val; \
  281                         b8[1] = val >> 8; \
  282                 } while(0)
  283 #define _PCM_WRITE_S32_LE(bb8, vval) do { \
  284                         int32_t val = (vval); \
  285                         uint8_t *b8 = (bb8); \
  286                         b8[0] = val; \
  287                         b8[1] = val >> 8; \
  288                         b8[2] = val >> 16; \
  289                         b8[3] = val >> 24; \
  290                 } while(0)
  291 #define PCM_WRITE_S16_BE(b8, val)       *((int16_t *)(b8)) = (val)
  292 #define _PCM_WRITE_S32_BE(b8, val)      *((int32_t *)(b8)) = (val)
  293 
  294 #define PCM_READ_U16_LE(b8) \
  295                 ((int32_t)((b8)[0] | ((int8_t)((b8)[1] ^ 0x80)) << 8))
  296 #define _PCM_READ_U32_LE(b8) \
  297                 ((int32_t)((b8)[0] | (b8)[1] << 8 | (b8)[2] << 16 | \
  298                         ((int8_t)((b8)[3] ^ 0x80)) << 24))
  299 #define PCM_READ_U16_BE(b8) ((int16_t)(*((uint16_t *)(b8)) ^ 0x8000))
  300 #define _PCM_READ_U32_BE(b8) ((int32_t)(*((uint32_t *)(b8)) ^ 0x80000000))
  301 
  302 #define PCM_WRITE_U16_LE(bb8, vval) do { \
  303                         int32_t val = (vval); \
  304                         uint8_t *b8 = (bb8); \
  305                         b8[0] = val; \
  306                         b8[1] = (val >> 8) ^ 0x80; \
  307                 } while(0)
  308 #define _PCM_WRITE_U32_LE(bb8, vval) do { \
  309                         int32_t val = (vval); \
  310                         uint8_t *b8 = (bb8); \
  311                         b8[0] = val; \
  312                         b8[1] = val >> 8; \
  313                         b8[2] = val >> 16; \
  314                         b8[3] = (val >> 24) ^ 0x80; \
  315                 } while(0)
  316 #define PCM_WRITE_U16_BE(b8, val)       *((uint16_t *)(b8)) = (val) ^ 0x8000
  317 #define _PCM_WRITE_U32_BE(b8, val)      *((uint32_t *)(b8)) = (val) ^ 0x80000000
  318 #endif
  319 
  320 #define PCM_READ_S24_LE(b8) \
  321                 ((int32_t)((b8)[0] | (b8)[1] << 8 | ((int8_t)((b8)[2])) << 16))
  322 #define PCM_READ_S24_BE(b8) \
  323                 ((int32_t)((b8)[2] | (b8)[1] << 8 | ((int8_t)((b8)[0])) << 16))
  324 
  325 #define PCM_WRITE_S24_LE(bb8, vval) do { \
  326                         int32_t val = (vval); \
  327                         uint8_t *b8 = (bb8); \
  328                         b8[0] = val; \
  329                         b8[1] = val >> 8; \
  330                         b8[2] = val >> 16; \
  331                 } while(0)
  332 #define PCM_WRITE_S24_BE(bb8, vval) do { \
  333                         int32_t val = (vval); \
  334                         uint8_t *b8 = (bb8); \
  335                         b8[2] = val; \
  336                         b8[1] = val >> 8; \
  337                         b8[0] = val >> 16; \
  338                 } while(0)
  339 
  340 #define PCM_READ_U24_LE(b8) \
  341                 ((int32_t)((b8)[0] | (b8)[1] << 8 | \
  342                         ((int8_t)((b8)[2] ^ 0x80)) << 16))
  343 #define PCM_READ_U24_BE(b8) \
  344                 ((int32_t)((b8)[2] | (b8)[1] << 8 | \
  345                         ((int8_t)((b8)[0] ^ 0x80)) << 16))
  346 
  347 #define PCM_WRITE_U24_LE(bb8, vval) do { \
  348                         int32_t val = (vval); \
  349                         uint8_t *b8 = (bb8); \
  350                         b8[0] = val; \
  351                         b8[1] = val >> 8; \
  352                         b8[2] = (val >> 16) ^ 0x80; \
  353                 } while(0)
  354 #define PCM_WRITE_U24_BE(bb8, vval) do { \
  355                         int32_t val = (vval); \
  356                         uint8_t *b8 = (bb8); \
  357                         b8[2] = val; \
  358                         b8[1] = val >> 8; \
  359                         b8[0] = (val >> 16) ^ 0x80; \
  360                 } while(0)
  361 
  362 #ifdef PCM_USE_64BIT_ARITH
  363 #define PCM_READ_S32_LE(b8)             _PCM_READ_S32_LE(b8)
  364 #define PCM_READ_S32_BE(b8)             _PCM_READ_S32_BE(b8)
  365 #define PCM_WRITE_S32_LE(b8, val)       _PCM_WRITE_S32_LE(b8, val)
  366 #define PCM_WRITE_S32_BE(b8, val)       _PCM_WRITE_S32_BE(b8, val)
  367 
  368 #define PCM_READ_U32_LE(b8)             _PCM_READ_U32_LE(b8)
  369 #define PCM_READ_U32_BE(b8)             _PCM_READ_U32_BE(b8)
  370 #define PCM_WRITE_U32_LE(b8, val)       _PCM_WRITE_U32_LE(b8, val)
  371 #define PCM_WRITE_U32_BE(b8, val)       _PCM_WRITE_U32_BE(b8, val)
  372 #else /* !PCM_USE_64BIT_ARITH */
  373 /*
  374  * 24bit integer ?!? This is quite unfortunate, eh? Get the fact straight:
  375  * Dynamic range for:
  376  *      1) Human =~ 140db
  377  *      2) 16bit = 96db (close enough)
  378  *      3) 24bit = 144db (perfect)
  379  *      4) 32bit = 196db (way too much)
  380  *      5) Bugs Bunny = Gazillion!@%$Erbzzztt-EINVAL db
  381  * Since we're not Bugs Bunny ..uh..err.. avoiding 64bit arithmetic, 24bit
  382  * is pretty much sufficient for our signed integer processing.
  383  */
  384 #define PCM_READ_S32_LE(b8)             (_PCM_READ_S32_LE(b8) >> PCM_FXSHIFT)
  385 #define PCM_READ_S32_BE(b8)             (_PCM_READ_S32_BE(b8) >> PCM_FXSHIFT)
  386 #define PCM_WRITE_S32_LE(b8, val)       _PCM_WRITE_S32_LE(b8, (val) << PCM_FXSHIFT)
  387 #define PCM_WRITE_S32_BE(b8, val)       _PCM_WRITE_S32_BE(b8, (val) << PCM_FXSHIFT)
  388 
  389 #define PCM_READ_U32_LE(b8)             (_PCM_READ_U32_LE(b8) >> PCM_FXSHIFT)
  390 #define PCM_READ_U32_BE(b8)             (_PCM_READ_U32_BE(b8) >> PCM_FXSHIFT)
  391 #define PCM_WRITE_U32_LE(b8, val)       _PCM_WRITE_U32_LE(b8, (val) << PCM_FXSHIFT)
  392 #define PCM_WRITE_U32_BE(b8, val)       _PCM_WRITE_U32_BE(b8, (val) << PCM_FXSHIFT)
  393 #endif
  394 
  395 /*
  396  * 8bit sample is pretty much useless since it doesn't provide
  397  * sufficient dynamic range throughout our filtering process.
  398  * For the sake of completeness, declare it anyway.
  399  */
  400 #define PCM_READ_S8(b8)                 *((int8_t *)(b8))
  401 #define PCM_READ_S8_NE(b8)              PCM_READ_S8(b8)
  402 #define PCM_READ_U8(b8)                 ((int8_t)(*((uint8_t *)(b8)) ^ 0x80))
  403 #define PCM_READ_U8_NE(b8)              PCM_READ_U8(b8)
  404 
  405 #define PCM_WRITE_S8(b8, val)           *((int8_t *)(b8)) = (val)
  406 #define PCM_WRITE_S8_NE(b8, val)        PCM_WRITE_S8(b8, val)
  407 #define PCM_WRITE_U8(b8, val)           *((uint8_t *)(b8)) = (val) ^ 0x80
  408 #define PCM_WRITE_U8_NE(b8, val)        PCM_WRITE_U8(b8, val)
  409 
  410 #define PCM_CLAMP_S8(val) \
  411                 (((val) > PCM_S8_MAX) ? PCM_S8_MAX : \
  412                         (((val) < PCM_S8_MIN) ? PCM_S8_MIN : (val)))
  413 #define PCM_CLAMP_S16(val) \
  414                 (((val) > PCM_S16_MAX) ? PCM_S16_MAX : \
  415                         (((val) < PCM_S16_MIN) ? PCM_S16_MIN : (val)))
  416 #define PCM_CLAMP_S24(val) \
  417                 (((val) > PCM_S24_MAX) ? PCM_S24_MAX : \
  418                         (((val) < PCM_S24_MIN) ? PCM_S24_MIN : (val)))
  419 
  420 #ifdef PCM_USE_64BIT_ARITH
  421 #define PCM_CLAMP_S32(val) \
  422                 (((val) > PCM_S32_MAX) ? PCM_S32_MAX : \
  423                         (((val) < PCM_S32_MIN) ? PCM_S32_MIN : (val)))
  424 #else
  425 #define PCM_CLAMP_S32(val) \
  426                 (((val) > PCM_S24_MAX) ? PCM_S32_MAX : \
  427                         (((val) < PCM_S24_MIN) ? PCM_S32_MIN : \
  428                         ((val) << PCM_FXSHIFT)))
  429 #endif
  430 
  431 #define PCM_CLAMP_U8(val)       PCM_CLAMP_S8(val)
  432 #define PCM_CLAMP_U16(val)      PCM_CLAMP_S16(val)
  433 #define PCM_CLAMP_U24(val)      PCM_CLAMP_S24(val)
  434 #define PCM_CLAMP_U32(val)      PCM_CLAMP_S32(val)
  435 
  436 /* make figuring out what a format is easier. got AFMT_STEREO already */
  437 #define AFMT_32BIT (AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE)
  438 #define AFMT_24BIT (AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE)
  439 #define AFMT_16BIT (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE)
  440 #define AFMT_8BIT (AFMT_MU_LAW | AFMT_A_LAW | AFMT_U8 | AFMT_S8)
  441 #define AFMT_SIGNED (AFMT_S32_LE | AFMT_S32_BE | AFMT_S24_LE | AFMT_S24_BE | \
  442                         AFMT_S16_LE | AFMT_S16_BE | AFMT_S8)
  443 #define AFMT_BIGENDIAN (AFMT_S32_BE | AFMT_U32_BE | AFMT_S24_BE | AFMT_U24_BE | \
  444                         AFMT_S16_BE | AFMT_U16_BE)
  445 
  446 struct pcm_channel *fkchan_setup(device_t dev);
  447 int fkchan_kill(struct pcm_channel *c);
  448 
  449 /*
  450  * Minor numbers for the sound driver.
  451  *
  452  * Unfortunately Creative called the codec chip of SB as a DSP. For this
  453  * reason the /dev/dsp is reserved for digitized audio use. There is a
  454  * device for true DSP processors but it will be called something else.
  455  * In v3.0 it's /dev/sndproc but this could be a temporary solution.
  456  */
  457 
  458 #define SND_DEV_CTL     0       /* Control port /dev/mixer */
  459 #define SND_DEV_SEQ     1       /* Sequencer /dev/sequencer */
  460 #define SND_DEV_MIDIN   2       /* Raw midi access */
  461 #define SND_DEV_DSP     3       /* Digitized voice /dev/dsp */
  462 #define SND_DEV_AUDIO   4       /* Sparc compatible /dev/audio */
  463 #define SND_DEV_DSP16   5       /* Like /dev/dsp but 16 bits/sample */
  464 #define SND_DEV_STATUS  6       /* /dev/sndstat */
  465                                 /* #7 not in use now. */
  466 #define SND_DEV_SEQ2    8       /* /dev/sequencer, level 2 interface */
  467 #define SND_DEV_SNDPROC 9       /* /dev/sndproc for programmable devices */
  468 #define SND_DEV_PSS     SND_DEV_SNDPROC /* ? */
  469 #define SND_DEV_NORESET 10
  470 
  471 #define SND_DEV_DSPHW_PLAY      11      /* specific playback channel */
  472 #define SND_DEV_DSPHW_VPLAY     12      /* specific virtual playback channel */
  473 #define SND_DEV_DSPHW_REC       13      /* specific record channel */
  474 #define SND_DEV_DSPHW_VREC      14      /* specific virtual record channel */
  475 
  476 #define SND_DEV_DSPHW_CD        15      /* s16le/stereo 44100Hz CD */
  477 
  478 #define SND_DEV_DSP_MMAP        16      /* OSSv4 compatible /dev/dsp_mmap */
  479 
  480 #define SND_DEV_LAST            SND_DEV_DSP_MMAP
  481 #define SND_DEV_MAX             PCMMAXDEV
  482 
  483 #define DSP_DEFAULT_SPEED       8000
  484 
  485 #define ON              1
  486 #define OFF             0
  487 
  488 extern int pcm_veto_load;
  489 extern int snd_unit;
  490 extern int snd_maxautovchans;
  491 extern int snd_verbose;
  492 extern devclass_t pcm_devclass;
  493 extern struct unrhdr *pcmsg_unrhdr;
  494 
  495 /*
  496  * some macros for debugging purposes
  497  * DDB/DEB to enable/disable debugging stuff
  498  * BVDDB   to enable debugging when bootverbose
  499  */
  500 #define BVDDB(x) if (bootverbose) x
  501 
  502 #ifndef DEB
  503 #define DEB(x)
  504 #endif
  505 
  506 SYSCTL_DECL(_hw_snd);
  507 
  508 struct pcm_channel *pcm_getfakechan(struct snddev_info *d);
  509 int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, pid_t pid, int devunit);
  510 int pcm_chnrelease(struct pcm_channel *c);
  511 int pcm_chnref(struct pcm_channel *c, int ref);
  512 int pcm_inprog(struct snddev_info *d, int delta);
  513 
  514 struct pcm_channel *pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, int num, void *devinfo);
  515 int pcm_chn_destroy(struct pcm_channel *ch);
  516 int pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch);
  517 int pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch);
  518 
  519 int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo);
  520 unsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz);
  521 int pcm_register(device_t dev, void *devinfo, int numplay, int numrec);
  522 int pcm_unregister(device_t dev);
  523 int pcm_setstatus(device_t dev, char *str);
  524 u_int32_t pcm_getflags(device_t dev);
  525 void pcm_setflags(device_t dev, u_int32_t val);
  526 void *pcm_getdevinfo(device_t dev);
  527 
  528 
  529 int snd_setup_intr(device_t dev, struct resource *res, int flags,
  530                    driver_intr_t hand, void *param, void **cookiep);
  531 
  532 void *snd_mtxcreate(const char *desc, const char *type);
  533 void snd_mtxfree(void *m);
  534 void snd_mtxassert(void *m);
  535 #define snd_mtxlock(m) mtx_lock(m)
  536 #define snd_mtxunlock(m) mtx_unlock(m)
  537 
  538 int sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS);
  539 
  540 typedef int (*sndstat_handler)(struct sbuf *s, device_t dev, int verbose);
  541 int sndstat_acquire(struct thread *td);
  542 int sndstat_release(struct thread *td);
  543 int sndstat_register(device_t dev, char *str, sndstat_handler handler);
  544 int sndstat_registerfile(char *str);
  545 int sndstat_unregister(device_t dev);
  546 int sndstat_unregisterfile(char *str);
  547 
  548 #define SND_DECLARE_FILE(version) \
  549         _SND_DECLARE_FILE(__LINE__, version)
  550 
  551 #define _SND_DECLARE_FILE(uniq, version) \
  552         __SND_DECLARE_FILE(uniq, version)
  553 
  554 #define __SND_DECLARE_FILE(uniq, version) \
  555         static char sndstat_vinfo[] = version; \
  556         SYSINIT(sdf_ ## uniq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_registerfile, sndstat_vinfo); \
  557         SYSUNINIT(sdf_ ## uniq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_unregisterfile, sndstat_vinfo);
  558 
  559 /* usage of flags in device config entry (config file) */
  560 #define DV_F_DRQ_MASK   0x00000007      /* mask for secondary drq */
  561 #define DV_F_DUAL_DMA   0x00000010      /* set to use secondary dma channel */
  562 
  563 /* ought to be made obsolete but still used by mss */
  564 #define DV_F_DEV_MASK   0x0000ff00      /* force device type/class */
  565 #define DV_F_DEV_SHIFT  8               /* force device type/class */
  566 
  567 #define PCM_DEBUG_MTX
  568 
  569 /*
  570  * this is rather kludgey- we need to duplicate these struct def'ns from sound.c
  571  * so that the macro versions of pcm_{,un}lock can dereference them.
  572  * we also have to do this now makedev() has gone away.
  573  */
  574 
  575 struct snddev_info {
  576         struct {
  577                 struct {
  578                         SLIST_HEAD(, pcm_channel) head;
  579                         struct {
  580                                 SLIST_HEAD(, pcm_channel) head;
  581                         } busy;
  582                 } pcm;
  583         } channels;
  584         TAILQ_HEAD(dsp_cdevinfo_linkhead, dsp_cdevinfo) dsp_cdevinfo_pool;
  585         struct snd_clone *clones;
  586         struct pcm_channel *fakechan;
  587         unsigned devcount, playcount, reccount, pvchancount, rvchancount ;
  588         unsigned flags;
  589         int inprog;
  590         unsigned int bufsz;
  591         void *devinfo;
  592         device_t dev;
  593         char status[SND_STATUSLEN];
  594         struct mtx *lock;
  595         struct cdev *mixer_dev;
  596         uint32_t pvchanrate, pvchanformat;
  597         uint32_t rvchanrate, rvchanformat;
  598         struct sysctl_ctx_list play_sysctl_ctx, rec_sysctl_ctx;
  599         struct sysctl_oid *play_sysctl_tree, *rec_sysctl_tree;
  600         struct cv cv;
  601 };
  602 
  603 void    sound_oss_sysinfo(oss_sysinfo *);
  604 
  605 #ifdef  PCM_DEBUG_MTX
  606 #define pcm_lock(d) mtx_lock(((struct snddev_info *)(d))->lock)
  607 #define pcm_unlock(d) mtx_unlock(((struct snddev_info *)(d))->lock)
  608 #else
  609 void pcm_lock(struct snddev_info *d);
  610 void pcm_unlock(struct snddev_info *d);
  611 #endif
  612 
  613 /*
  614  * For PCM_CV_[WAIT | ACQUIRE | RELEASE], be sure to surround these
  615  * with pcm_lock/unlock() sequence, or I'll come to gnaw upon you!
  616  */
  617 #ifdef SND_DIAGNOSTIC
  618 #define PCM_WAIT(x)             do {                                    \
  619         if (mtx_owned((x)->lock) == 0)                                  \
  620                 panic("%s(%d): [PCM WAIT] Mutex not owned!",            \
  621                     __func__, __LINE__);                                \
  622         while ((x)->flags & SD_F_BUSY) {                                \
  623                 if (snd_verbose > 3)                                    \
  624                         device_printf((x)->dev,                         \
  625                             "%s(%d): [PCM WAIT] calling cv_wait().\n",  \
  626                             __func__, __LINE__);                        \
  627                 cv_wait(&(x)->cv, (x)->lock);                           \
  628         }                                                               \
  629 } while(0)
  630 
  631 #define PCM_ACQUIRE(x)          do {                                    \
  632         if (mtx_owned((x)->lock) == 0)                                  \
  633                 panic("%s(%d): [PCM ACQUIRE] Mutex not owned!",         \
  634                     __func__, __LINE__);                                \
  635         if ((x)->flags & SD_F_BUSY)                                     \
  636                 panic("%s(%d): [PCM ACQUIRE] "                          \
  637                     "Trying to acquire BUSY cv!", __func__, __LINE__);  \
  638         (x)->flags |= SD_F_BUSY;                                        \
  639 } while(0)
  640 
  641 #define PCM_RELEASE(x)          do {                                    \
  642         if (mtx_owned((x)->lock) == 0)                                  \
  643                 panic("%s(%d): [PCM RELEASE] Mutex not owned!",         \
  644                     __func__, __LINE__);                                \
  645         if ((x)->flags & SD_F_BUSY) {                                   \
  646                 (x)->flags &= ~SD_F_BUSY;                               \
  647                 if ((x)->cv.cv_waiters != 0) {                          \
  648                         if ((x)->cv.cv_waiters > 1 && snd_verbose > 3)  \
  649                                 device_printf((x)->dev,                 \
  650                                     "%s(%d): [PCM RELEASE] "            \
  651                                     "cv_waiters=%d > 1!\n",             \
  652                                     __func__, __LINE__,                 \
  653                                     (x)->cv.cv_waiters);                \
  654                         cv_broadcast(&(x)->cv);                         \
  655                 }                                                       \
  656         } else                                                          \
  657                 panic("%s(%d): [PCM RELEASE] Releasing non-BUSY cv!",   \
  658                     __func__, __LINE__);                                \
  659 } while(0)
  660 
  661 /* Quick version, for shorter path. */
  662 #define PCM_ACQUIRE_QUICK(x)    do {                                    \
  663         if (mtx_owned((x)->lock) != 0)                                  \
  664                 panic("%s(%d): [PCM ACQUIRE QUICK] Mutex owned!",       \
  665                     __func__, __LINE__);                                \
  666         pcm_lock(x);                                                    \
  667         PCM_WAIT(x);                                                    \
  668         PCM_ACQUIRE(x);                                                 \
  669         pcm_unlock(x);                                                  \
  670 } while(0)
  671 
  672 #define PCM_RELEASE_QUICK(x)    do {                                    \
  673         if (mtx_owned((x)->lock) != 0)                                  \
  674                 panic("%s(%d): [PCM RELEASE QUICK] Mutex owned!",       \
  675                     __func__, __LINE__);                                \
  676         pcm_lock(x);                                                    \
  677         PCM_RELEASE(x);                                                 \
  678         pcm_unlock(x);                                                  \
  679 } while(0)
  680 
  681 #define PCM_BUSYASSERT(x)       do {                                    \
  682         if (!((x) != NULL && ((x)->flags & SD_F_BUSY)))                 \
  683                 panic("%s(%d): [PCM BUSYASSERT] "                       \
  684                     "Failed, snddev_info=%p", __func__, __LINE__, x);   \
  685 } while(0)
  686 
  687 #define PCM_GIANT_ENTER(x)      do {                                    \
  688         int _pcm_giant = 0;                                             \
  689         if (mtx_owned((x)->lock) != 0)                                  \
  690                 panic("%s(%d): [GIANT ENTER] PCM lock owned!",          \
  691                     __func__, __LINE__);                                \
  692         if (mtx_owned(&Giant) != 0 && snd_verbose > 3)                  \
  693                 device_printf((x)->dev,                                 \
  694                     "%s(%d): [GIANT ENTER] Giant owned!\n",             \
  695                     __func__, __LINE__);                                \
  696         if (!((x)->flags & SD_F_MPSAFE) && mtx_owned(&Giant) == 0)      \
  697                 do {                                                    \
  698                         mtx_lock(&Giant);                               \
  699                         _pcm_giant = 1;                                 \
  700                 } while(0)
  701 
  702 #define PCM_GIANT_EXIT(x)       do {                                    \
  703         if (mtx_owned((x)->lock) != 0)                                  \
  704                 panic("%s(%d): [GIANT EXIT] PCM lock owned!",           \
  705                     __func__, __LINE__);                                \
  706         if (!(_pcm_giant == 0 || _pcm_giant == 1))                      \
  707                 panic("%s(%d): [GIANT EXIT] _pcm_giant screwed!",       \
  708                     __func__, __LINE__);                                \
  709         if ((x)->flags & SD_F_MPSAFE) {                                 \
  710                 if (_pcm_giant == 1)                                    \
  711                         panic("%s(%d): [GIANT EXIT] MPSAFE Giant?",     \
  712                             __func__, __LINE__);                        \
  713                 if (mtx_owned(&Giant) != 0 && snd_verbose > 3)          \
  714                         device_printf((x)->dev,                         \
  715                             "%s(%d): [GIANT EXIT] Giant owned!\n",      \
  716                             __func__, __LINE__);                        \
  717         }                                                               \
  718         if (_pcm_giant != 0) {                                          \
  719                 if (mtx_owned(&Giant) == 0)                             \
  720                         panic("%s(%d): [GIANT EXIT] Giant not owned!",  \
  721                             __func__, __LINE__);                        \
  722                 _pcm_giant = 0;                                         \
  723                 mtx_unlock(&Giant);                                     \
  724         }                                                               \
  725 } while(0)
  726 #else /* SND_DIAGNOSTIC */
  727 #define PCM_WAIT(x)             do {                                    \
  728         mtx_assert((x)->lock, MA_OWNED);                                \
  729         while ((x)->flags & SD_F_BUSY)                                  \
  730                 cv_wait(&(x)->cv, (x)->lock);                           \
  731 } while(0)
  732 
  733 #define PCM_ACQUIRE(x)          do {                                    \
  734         mtx_assert((x)->lock, MA_OWNED);                                \
  735         KASSERT(!((x)->flags & SD_F_BUSY),                              \
  736             ("%s(%d): [PCM ACQUIRE] Trying to acquire BUSY cv!",        \
  737             __func__, __LINE__));                                       \
  738         (x)->flags |= SD_F_BUSY;                                        \
  739 } while(0)
  740 
  741 #define PCM_RELEASE(x)          do {                                    \
  742         mtx_assert((x)->lock, MA_OWNED);                                \
  743         KASSERT((x)->flags & SD_F_BUSY,                                 \
  744             ("%s(%d): [PCM RELEASE] Releasing non-BUSY cv!",            \
  745             __func__, __LINE__));                                       \
  746         (x)->flags &= ~SD_F_BUSY;                                       \
  747         if ((x)->cv.cv_waiters != 0)                                    \
  748                 cv_broadcast(&(x)->cv);                                 \
  749 } while(0)
  750 
  751 /* Quick version, for shorter path. */
  752 #define PCM_ACQUIRE_QUICK(x)    do {                                    \
  753         mtx_assert((x)->lock, MA_NOTOWNED);                             \
  754         pcm_lock(x);                                                    \
  755         PCM_WAIT(x);                                                    \
  756         PCM_ACQUIRE(x);                                                 \
  757         pcm_unlock(x);                                                  \
  758 } while(0)
  759 
  760 #define PCM_RELEASE_QUICK(x)    do {                                    \
  761         mtx_assert((x)->lock, MA_NOTOWNED);                             \
  762         pcm_lock(x);                                                    \
  763         PCM_RELEASE(x);                                                 \
  764         pcm_unlock(x);                                                  \
  765 } while(0)
  766 
  767 #define PCM_BUSYASSERT(x)       KASSERT(x != NULL &&                    \
  768                                     ((x)->flags & SD_F_BUSY),           \
  769                                     ("%s(%d): [PCM BUSYASSERT] "        \
  770                                     "Failed, snddev_info=%p",           \
  771                                     __func__, __LINE__, x))
  772 
  773 #define PCM_GIANT_ENTER(x)      do {                                    \
  774         int _pcm_giant = 0;                                             \
  775         mtx_assert((x)->lock, MA_NOTOWNED);                             \
  776         if (!((x)->flags & SD_F_MPSAFE) && mtx_owned(&Giant) == 0)      \
  777                 do {                                                    \
  778                         mtx_lock(&Giant);                               \
  779                         _pcm_giant = 1;                                 \
  780                 } while(0)
  781 
  782 #define PCM_GIANT_EXIT(x)       do {                                    \
  783         mtx_assert((x)->lock, MA_NOTOWNED);                             \
  784         KASSERT(_pcm_giant == 0 || _pcm_giant == 1,                     \
  785             ("%s(%d): [GIANT EXIT] _pcm_giant screwed!",                \
  786             __func__, __LINE__));                                       \
  787         KASSERT(!((x)->flags & SD_F_MPSAFE) ||                          \
  788             (((x)->flags & SD_F_MPSAFE) && _pcm_giant == 0),            \
  789             ("%s(%d): [GIANT EXIT] MPSAFE Giant?",                      \
  790             __func__, __LINE__));                                       \
  791         if (_pcm_giant != 0) {                                          \
  792                 mtx_assert(&Giant, MA_OWNED);                           \
  793                 _pcm_giant = 0;                                         \
  794                 mtx_unlock(&Giant);                                     \
  795         }                                                               \
  796 } while(0)
  797 #endif /* !SND_DIAGNOSTIC */
  798 
  799 #define PCM_GIANT_LEAVE(x)                                              \
  800         PCM_GIANT_EXIT(x);                                              \
  801 } while(0)
  802 
  803 #ifdef KLD_MODULE
  804 #define PCM_KLDSTRING(a) ("kld " # a)
  805 #else
  806 #define PCM_KLDSTRING(a) ""
  807 #endif
  808 
  809 #endif /* _KERNEL */
  810 
  811 #endif  /* _OS_H_ */

Cache object: 6136ac63f2accaeccc7fb377121c4fad


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