FreeBSD kernel sound device code
dsp.c File Reference
#include <dev/sound/pcm/sound.h>
#include <sys/ctype.h>
#include <sys/lock.h>
#include <sys/rwlock.h>
#include <sys/sysent.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
Include dependency graph for dsp.c:

Go to the source code of this file.

Data Structures

struct  dsp_cdevinfo
 

Macros

#define PCM_RDCH(x)   (((struct dsp_cdevinfo *)(x)->si_drv1)->rdch)
 
#define PCM_WRCH(x)   (((struct dsp_cdevinfo *)(x)->si_drv1)->wrch)
 
#define PCM_VOLCH(x)   (((struct dsp_cdevinfo *)(x)->si_drv1)->volch)
 
#define PCM_SIMPLEX(x)   (((struct dsp_cdevinfo *)(x)->si_drv1)->simplex)
 
#define DSP_CDEVINFO_CACHESIZE   8
 
#define DSP_REGISTERED(x, y)
 
#define OLDPCM_IOCTL
 
#define DSP_F_VALID(x)   ((x) & (FREAD | FWRITE))
 
#define DSP_F_DUPLEX(x)   (((x) & (FREAD | FWRITE)) == (FREAD | FWRITE))
 
#define DSP_F_SIMPLEX(x)   (!DSP_F_DUPLEX(x))
 
#define DSP_F_READ(x)   ((x) & FREAD)
 
#define DSP_F_WRITE(x)   ((x) & FWRITE)
 
#define DSP_FIXUP_ERROR()
 
#define THE_REAL_SNDCTL_DSP_GETBLKSIZE   _IOWR('P', 4, int)
 

Enumerations

enum  { DSP_CDEV_TYPE_RDONLY , DSP_CDEV_TYPE_WRONLY , DSP_CDEV_TYPE_RDWR }
 
enum  { DSP_CDEV_VOLCTL_NONE , DSP_CDEV_VOLCTL_READ , DSP_CDEV_VOLCTL_WRITE }
 

Functions

 SND_DECLARE_FILE ("$FreeBSD$")
 
 SYSCTL_INT (_hw_snd, OID_AUTO, compat_linux_mmap, CTLFLAG_RWTUN, &dsp_mmap_allow_prot_exec, 0, "linux mmap compatibility (-1=force disable 0=auto 1=force enable)")
 
 SYSCTL_INT (_hw_snd, OID_AUTO, basename_clone, CTLFLAG_RWTUN, &dsp_basename_clone, 0, "DSP basename cloning (0: Disable; 1: Enabled)")
 
static int dsp_oss_syncgroup (struct pcm_channel *wrch, struct pcm_channel *rdch, oss_syncgroup *group)
 Assigns a PCM channel to a sync group. More...
 
static int dsp_oss_syncstart (int sg_id)
 Launch a sync group into action. More...
 
static int dsp_oss_policy (struct pcm_channel *wrch, struct pcm_channel *rdch, int policy)
 Handler for SNDCTL_DSP_POLICY. More...
 
static int dsp_oss_cookedmode (struct pcm_channel *wrch, struct pcm_channel *rdch, int enabled)
 Enable or disable "cooked" mode. More...
 
static int dsp_oss_getchnorder (struct pcm_channel *wrch, struct pcm_channel *rdch, unsigned long long *map)
 Retrieve channel interleaving order. More...
 
static int dsp_oss_setchnorder (struct pcm_channel *wrch, struct pcm_channel *rdch, unsigned long long *map)
 Specify channel interleaving order. More...
 
static int dsp_oss_getchannelmask (struct pcm_channel *wrch, struct pcm_channel *rdch, int *mask)
 
static struct snddev_infodsp_get_info (struct cdev *dev)
 
static uint32_t dsp_get_flags (struct cdev *dev)
 
static void dsp_set_flags (struct cdev *dev, uint32_t flags)
 
static int getchns (struct cdev *dev, struct pcm_channel **rdch, struct pcm_channel **wrch, uint32_t prio)
 
static void relchns (struct cdev *dev, struct pcm_channel *rdch, struct pcm_channel *wrch, uint32_t prio)
 
static void dsp_cdevinfo_alloc (struct cdev *dev, struct pcm_channel *rdch, struct pcm_channel *wrch, struct pcm_channel *volch)
 
static void dsp_cdevinfo_free (struct cdev *dev)
 
void dsp_cdevinfo_init (struct snddev_info *d)
 
void dsp_cdevinfo_flush (struct snddev_info *d)
 
static int dsp_open (struct cdev *i_dev, int flags, int mode, struct thread *td)
 
static int dsp_close (struct cdev *i_dev, int flags, int mode, struct thread *td)
 
static __inline int dsp_io_ops (struct cdev *i_dev, struct uio *buf)
 
static int dsp_read (struct cdev *i_dev, struct uio *buf, int flag)
 
static int dsp_write (struct cdev *i_dev, struct uio *buf, int flag)
 
static int dsp_get_volume_channel (struct cdev *dev, struct pcm_channel **volch)
 
static int dsp_ioctl_channel (struct cdev *dev, struct pcm_channel *volch, u_long cmd, caddr_t arg)
 
static int dsp_ioctl (struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
 
static int dsp_poll (struct cdev *i_dev, int events, struct thread *td)
 
static int dsp_mmap (struct cdev *i_dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr)
 
static int dsp_mmap_single (struct cdev *i_dev, vm_ooffset_t *offset, vm_size_t size, struct vm_object **object, int nprot)
 
static int dsp_stdclone (char *name, char *namep, char *sep, int use_sep, int *u, int *c)
 
static void dsp_clone (void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev)
 
static void dsp_sysinit (void *p)
 
static void dsp_sysuninit (void *p)
 
 SYSINIT (dsp_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, dsp_sysinit, NULL)
 
 SYSUNINIT (dsp_sysuninit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, dsp_sysuninit, NULL)
 
char * dsp_unit2name (char *buf, size_t len, int unit)
 
int dsp_oss_audioinfo (struct cdev *i_dev, oss_audioinfo *ai)
 Handler for SNDCTL_AUDIOINFO. More...
 

Variables

static int dsp_mmap_allow_prot_exec = 0
 
static int dsp_basename_clone = 1
 
static d_open_t dsp_open
 
static d_close_t dsp_close
 
static d_read_t dsp_read
 
static d_write_t dsp_write
 
static d_ioctl_t dsp_ioctl
 
static d_poll_t dsp_poll
 
static d_mmap_t dsp_mmap
 
static d_mmap_single_t dsp_mmap_single
 
struct cdevsw dsp_cdevsw
 
static eventhandler_tag dsp_ehtag = NULL
 
static int dsp_umax = -1
 
static int dsp_cmax = -1
 
struct {
   int   type
 
   char *   name
 
   char *   sep
 
   char *   alias
 
   int   use_sep
 
   int   hw
 
   int   max
 
   int   volctl
 
   uint32_t   fmt
 
   uint32_t   spd
 
   int   query
 
dsp_cdevs []
 

Macro Definition Documentation

◆ DSP_CDEVINFO_CACHESIZE

#define DSP_CDEVINFO_CACHESIZE   8

Definition at line 70 of file dsp.c.

◆ DSP_F_DUPLEX

#define DSP_F_DUPLEX (   x)    (((x) & (FREAD | FWRITE)) == (FREAD | FWRITE))

Definition at line 380 of file dsp.c.

◆ DSP_F_READ

#define DSP_F_READ (   x)    ((x) & FREAD)

Definition at line 382 of file dsp.c.

◆ DSP_F_SIMPLEX

#define DSP_F_SIMPLEX (   x)    (!DSP_F_DUPLEX(x))

Definition at line 381 of file dsp.c.

◆ DSP_F_VALID

#define DSP_F_VALID (   x)    ((x) & (FREAD | FWRITE))

Definition at line 379 of file dsp.c.

◆ DSP_F_WRITE

#define DSP_F_WRITE (   x)    ((x) & FWRITE)

Definition at line 383 of file dsp.c.

◆ DSP_FIXUP_ERROR

#define DSP_FIXUP_ERROR ( )
Value:
do { \
prio = dsp_get_flags(i_dev); \
if (!DSP_F_VALID(flags)) \
error = EINVAL; \
if (!DSP_F_DUPLEX(flags) && \
((DSP_F_READ(flags) && d->reccount == 0) || \
(DSP_F_WRITE(flags) && d->playcount == 0))) \
error = ENOTSUP; \
else if (!DSP_F_DUPLEX(flags) && (prio & SD_F_SIMPLEX) && \
((DSP_F_READ(flags) && (prio & SD_F_PRIO_WR)) || \
(DSP_F_WRITE(flags) && (prio & SD_F_PRIO_RD)))) \
error = EBUSY; \
else if (DSP_REGISTERED(d, i_dev)) \
error = EBUSY; \
} while (0)
static uint32_t dsp_get_flags(struct cdev *dev)
Definition: dsp.c:125
#define DSP_F_VALID(x)
Definition: dsp.c:379
#define DSP_F_READ(x)
Definition: dsp.c:382
#define DSP_REGISTERED(x, y)
Definition: dsp.c:72
#define DSP_F_WRITE(x)
Definition: dsp.c:383
#define DSP_F_DUPLEX(x)
Definition: dsp.c:380
#define SD_F_PRIO_RD
Definition: sound.h:151
#define SD_F_PRIO_WR
Definition: sound.h:152
#define SD_F_SIMPLEX
Definition: sound.h:132

Definition at line 434 of file dsp.c.

◆ DSP_REGISTERED

#define DSP_REGISTERED (   x,
 
)
Value:
(PCM_REGISTERED(x) && \
(y) != NULL && (y)->si_drv1 != NULL)
#define PCM_REGISTERED(x)
Definition: sound.h:178

Definition at line 72 of file dsp.c.

◆ OLDPCM_IOCTL

#define OLDPCM_IOCTL

Definition at line 75 of file dsp.c.

◆ PCM_RDCH

#define PCM_RDCH (   x)    (((struct dsp_cdevinfo *)(x)->si_drv1)->rdch)

Definition at line 65 of file dsp.c.

◆ PCM_SIMPLEX

#define PCM_SIMPLEX (   x)    (((struct dsp_cdevinfo *)(x)->si_drv1)->simplex)

Definition at line 68 of file dsp.c.

◆ PCM_VOLCH

#define PCM_VOLCH (   x)    (((struct dsp_cdevinfo *)(x)->si_drv1)->volch)

Definition at line 67 of file dsp.c.

◆ PCM_WRCH

#define PCM_WRCH (   x)    (((struct dsp_cdevinfo *)(x)->si_drv1)->wrch)

Definition at line 66 of file dsp.c.

◆ THE_REAL_SNDCTL_DSP_GETBLKSIZE

#define THE_REAL_SNDCTL_DSP_GETBLKSIZE   _IOWR('P', 4, int)

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
DSP_CDEV_TYPE_RDONLY 
DSP_CDEV_TYPE_WRONLY 
DSP_CDEV_TYPE_RDWR 

Definition at line 367 of file dsp.c.

◆ anonymous enum

anonymous enum
Enumerator
DSP_CDEV_VOLCTL_NONE 
DSP_CDEV_VOLCTL_READ 
DSP_CDEV_VOLCTL_WRITE 

Definition at line 373 of file dsp.c.

Function Documentation

◆ dsp_cdevinfo_alloc()

static void dsp_cdevinfo_alloc ( struct cdev *  dev,
struct pcm_channel rdch,
struct pcm_channel wrch,
struct pcm_channel volch 
)
static

Definition at line 227 of file dsp.c.

References dsp_cdevinfo::busy, dev, dsp_get_flags(), dsp_get_info(), PCM_BUSYASSERT, PCM_LOCK, PCM_LOCKASSERT, PCM_REGISTERED, PCM_UNLOCK, dsp_cdevinfo::rdch, SD_F_SIMPLEX, dsp_cdevinfo::simplex, dsp_cdevinfo::volch, and dsp_cdevinfo::wrch.

Referenced by dsp_open().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_cdevinfo_flush()

void dsp_cdevinfo_flush ( struct snddev_info d)

Definition at line 349 of file dsp.c.

References free, PCM_BUSYASSERT, and PCM_UNLOCKASSERT.

Referenced by pcm_unregister().

Here is the caller graph for this function:

◆ dsp_cdevinfo_free()

static void dsp_cdevinfo_free ( struct cdev *  dev)
static

Definition at line 275 of file dsp.c.

References dsp_cdevinfo::busy, dev, DSP_CDEVINFO_CACHESIZE, dsp_get_flags(), dsp_get_info(), dsp_set_flags(), free, PCM_BUSYASSERT, PCM_LOCKASSERT, PCM_RDCH, PCM_REGISTERED, PCM_VOLCH, PCM_WRCH, dsp_cdevinfo::rdch, SD_F_PRIO_RD, SD_F_PRIO_WR, dsp_cdevinfo::simplex, dsp_cdevinfo::volch, and dsp_cdevinfo::wrch.

Referenced by dsp_close().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_cdevinfo_init()

void dsp_cdevinfo_init ( struct snddev_info d)

Definition at line 332 of file dsp.c.

References DSP_CDEVINFO_CACHESIZE, PCM_BUSYASSERT, and PCM_UNLOCKASSERT.

Referenced by pcm_register().

Here is the caller graph for this function:

◆ dsp_clone()

◆ dsp_close()

◆ dsp_get_flags()

static uint32_t dsp_get_flags ( struct cdev *  dev)
static

Definition at line 125 of file dsp.c.

References dev, pcm_devclass, pcm_getflags(), and PCMUNIT.

Referenced by dsp_cdevinfo_alloc(), dsp_cdevinfo_free(), dsp_ioctl(), dsp_ioctl_channel(), and getchns().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_get_info()

static struct snddev_info * dsp_get_info ( struct cdev *  dev)
static

Definition at line 119 of file dsp.c.

References dev, pcm_devclass, and PCMUNIT.

Referenced by dsp_cdevinfo_alloc(), dsp_cdevinfo_free(), dsp_close(), dsp_get_volume_channel(), dsp_io_ops(), dsp_ioctl(), dsp_ioctl_channel(), dsp_mmap_single(), dsp_open(), dsp_poll(), and getchns().

Here is the caller graph for this function:

◆ dsp_get_volume_channel()

static int dsp_get_volume_channel ( struct cdev *  dev,
struct pcm_channel **  volch 
)
static

Definition at line 907 of file dsp.c.

References c, pcm_channel::channels, CHN_FOREACH, CHN_LOCK, CHN_UNLOCK, dev, dsp_get_info(), FEEDER_VOLUME, pcm_channel::feederflags, PCM_ACQUIRE, pcm_chnref(), PCM_LOCK, PCM_REGISTERED, PCM_RELEASE, PCM_UNLOCK, PCM_UNLOCKASSERT, PCM_VOLCH, PCM_WAIT, and pcm_channel::unit.

Referenced by dsp_ioctl_channel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_io_ops()

static __inline int dsp_io_ops ( struct cdev *  i_dev,
struct uio *  buf 
)
static

Definition at line 819 of file dsp.c.

References buf, CHN_BROADCAST, CHN_F_BUSY, CHN_F_DEAD, CHN_F_MMAP, CHN_F_RUNNING, chn_read(), chn_write(), dsp_get_info(), DSP_REGISTERED, getchns(), PCM_DETACHING, PCM_GIANT_ENTER, PCM_GIANT_EXIT, PCM_GIANT_LEAVE, relchns(), SD_F_PRIO_RD, and SD_F_PRIO_WR.

Referenced by dsp_read(), and dsp_write().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_ioctl()

static int dsp_ioctl ( struct cdev *  i_dev,
u_long  cmd,
caddr_t  arg,
int  mode,
struct thread *  td 
)
static
Note
Changing formats resets the buffer counters, which differs from the 4Front drivers. However, I don't expect this to be much of a problem.
In a test where CURRENT_OPTR is called immediately after write returns, this driver is about 32K samples behind whereas 4Front's is about 8K samples behind. Should determine source of discrepancy, even if only out of curiosity.
Todo:
Actually test SNDCTL_DSP_CURRENT_IPTR.

Definition at line 1099 of file dsp.c.

References AFMT_16BIT, AFMT_24BIT, AFMT_32BIT, AFMT_8BIT, AFMT_CHANNEL, AFMT_ENCODING, AFMT_EXTCHANNEL, b, pcm_channel::blocks, pcm_channel::bufsoft, chan, CHN_2NDBUFMAXSIZE, chn_abort(), CHN_F_DEAD, CHN_F_NBIO, CHN_F_NOTRIGGER, CHN_F_TRIGGERED, CHN_F_VIRTUAL, chn_getcaps(), chn_getformats(), chn_getptr(), CHN_LOCK, chn_resetbuf(), chn_setblocksize(), chn_setformat(), chn_setspeed(), chn_start(), chn_sync(), CHN_UNLOCK, pcm_channel::cv, DEB, dsp_get_flags(), dsp_get_info(), dsp_ioctl_channel(), dsp_oss_audioinfo(), dsp_oss_cookedmode(), dsp_oss_getchannelmask(), dsp_oss_getchnorder(), dsp_oss_policy(), dsp_oss_setchnorder(), dsp_oss_syncgroup(), dsp_oss_syncstart(), DSP_REGISTERED, dsp_set_flags(), pcmchan_matrix::ext, feeder_matrix_default_channel_map(), pcm_channel::flags, pcm_channel::format, getchns(), pcm_channel::inprog, pcm_channel::lock, lpeak, pcm_channel::lw, m, max, pcmchan_caps::maxspeed, pcmchan_caps::minspeed, mix_getdevs(), MIXER_CMD_DIRECT, snddev_info::mixer_dev, mixer_ioctl_cmd(), mixer_oss_mixerinfo(), pcm_channel::name, PCM_ACQUIRE_QUICK, PCM_DETACHING, PCM_GIANT_ENTER, PCM_GIANT_EXIT, PCM_GIANT_LEAVE, PCM_LOCK, PCM_RELEASE_QUICK, PCM_UNLOCK, PCM_VOLCH, RANGE, rpeak, SD_F_BITPERFECT, SD_F_SIMPLEX, snd_dbuf::shadbuf, snd_dbuf::sl, SND_CHN_MAX, SND_FORMAT, sndbuf_acquire(), sndbuf_dispose(), sndbuf_fillsilence(), sndbuf_getalign(), sndbuf_getblkcnt(), sndbuf_getblksz(), sndbuf_getblocks(), sndbuf_getfree(), sndbuf_getfreeptr(), sndbuf_gethwptr(), sndbuf_getready(), sndbuf_getreadyptr(), sndbuf_getsize(), sndbuf_gettotal(), sndbuf_softreset(), sound_oss_card_info(), sound_oss_sysinfo(), pcm_channel::speed, THE_REAL_SNDCTL_DSP_GETBLKSIZE, and pcm_channel::xruns.

Here is the call graph for this function:

◆ dsp_ioctl_channel()

static int dsp_ioctl_channel ( struct cdev *  dev,
struct pcm_channel volch,
u_long  cmd,
caddr_t  arg 
)
static

◆ dsp_mmap()

static int dsp_mmap ( struct cdev *  i_dev,
vm_ooffset_t  offset,
vm_paddr_t *  paddr,
int  nprot,
vm_memattr_t *  memattr 
)
static

Definition at line 2240 of file dsp.c.

References offset.

◆ dsp_mmap_single()

static int dsp_mmap_single ( struct cdev *  i_dev,
vm_ooffset_t *  offset,
vm_size_t  size,
struct vm_object **  object,
int  nprot 
)
static

◆ dsp_open()

◆ dsp_oss_audioinfo()

int dsp_oss_audioinfo ( struct cdev *  i_dev,
oss_audioinfo *  ai 
)

Handler for SNDCTL_AUDIOINFO.

Gathers information about the audio device specified in ai->dev. If ai->dev == -1, then this function gathers information about the current device. If the call comes in on a non-audio device and ai->dev == -1, return EINVAL.

This routine is supposed to go practically straight to the hardware, getting capabilities directly from the sound card driver, side-stepping the intermediate channel interface.

Note, however, that the usefulness of this command is significantly decreased when requesting info about any device other than the one serving the request. While each snddev_channel refers to a specific device node, the converse is not true. Currently, when a sound device node is opened, the sound subsystem scans for an available audio channel (or channels, if opened in read+write) and then assigns them to the si_drv[12] private data fields. As a result, any information returned linking a channel to a specific character device isn't necessarily accurate.

Note
Calling threads must not hold any snddev_info or pcm_channel locks.
Parameters
devdevice on which the ioctl was issued
aiioctl request data container
Return values
0success
EINVALai->dev specifies an invalid device
Todo:
Verify correctness of Doxygen tags. ;)
Note
cmd - OSSv4 docs: "Only supported under Linux at this moment." Cop-out, I know, but I'll save running around in the process table for later. Is there a risk of leaking information?
Todo:
SNDCTL_AUDIOINFO::caps - Make drivers keep these in pcmchan::caps?
Note
magic - OSSv4 docs: "Reserved for internal use by OSS."
card_number - OSSv4 docs: "Number of the sound card where this device belongs or -1 if this information is not available. Applications should normally not use this field for any purpose."
Todo:
song_name - depends first on SNDCTL_[GS]ETSONG
Todo:
Todo:
label - depends on SNDCTL_[GS]ETLABEL
Todo:
Todo:
port_number - routing information?
Note
real_device - OSSv4 docs: "Obsolete."
flags - OSSv4 docs: "Reserved for future use."
binding - OSSv4 docs: "Reserved for future use."
Todo:
handle - haven't decided how to generate this yet; bus, vendor, device IDs?

Definition at line 2587 of file dsp.c.

References AFMT_CHANNEL, buf, pcmchan_caps::caps, snddev_info::channels, CHN_F_BUSY, CHN_F_VIRTUAL, CHN_FOREACH, chn_getcaps(), chn_getrates(), CHN_LOCK, CHN_NAMELEN, CHN_UNLOCK, CHN_UNLOCKASSERT, snddev_info::dev, pcm_channel::direction, dsp_cdevsw, DSP_REGISTERED, dsp_unit2name(), pcm_channel::flags, pcmchan_caps::fmtlist, fmts, pcmchan_caps::maxspeed, pcmchan_caps::minspeed, snddev_info::mixer_dev, pcm_channel::name, pcm_devclass, PCM_LOCK, PCM_RDCH, PCM_REGISTERED, PCM_UNLOCK, PCM_UNLOCKASSERT, PCM_WRCH, PCMDIR_PLAY, PCMUNIT, pcm_channel::pid, rates, and pcm_channel::unit.

Referenced by dsp_ioctl(), and mixer_ioctl_cmd().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_oss_cookedmode()

static int dsp_oss_cookedmode ( struct pcm_channel wrch,
struct pcm_channel rdch,
int  enabled 
)
static

Enable or disable "cooked" mode.

This is a handler for SNDCTL_DSP_COOKEDMODE. When in cooked mode, which is the default, the sound system handles rate and format conversions automatically (ex: user writing 11025Hz/8 bit/unsigned but card only operates with 44100Hz/16bit/signed samples).

Disabling cooked mode is intended for applications wanting to mmap() a sound card's buffer space directly, bypassing the FreeBSD 2-stage feeder architecture, presumably to gain as much control over audio hardware as possible.

See http://manuals.opensound.com/developer/SNDCTL_DSP_COOKEDMODE.html for more details.

Parameters
wrchplayback channel (optional; may be NULL)
rdchrecording channel (optional; may be NULL)
enabled0 = raw mode, 1 = cooked mode
Return values
EINVALOperation not yet supported.

Definition at line 3146 of file dsp.c.

References CHN_F_BITPERFECT, CHN_LOCK, CHN_UNLOCK, and pcm_channel::flags.

Referenced by dsp_ioctl().

Here is the caller graph for this function:

◆ dsp_oss_getchannelmask()

static int dsp_oss_getchannelmask ( struct pcm_channel wrch,
struct pcm_channel rdch,
int *  mask 
)
static

Definition at line 3253 of file dsp.c.

References CHN_LOCK, chn_oss_getmask(), CHN_UNLOCK, and mask.

Referenced by dsp_ioctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_oss_getchnorder()

static int dsp_oss_getchnorder ( struct pcm_channel wrch,
struct pcm_channel rdch,
unsigned long long *  map 
)
static

Retrieve channel interleaving order.

This is the handler for SNDCTL_DSP_GET_CHNORDER.

See http://manuals.opensound.com/developer/SNDCTL_DSP_GET_CHNORDER.html for more details.

Note
As the ioctl definition is still under construction, FreeBSD does not currently support SNDCTL_DSP_GET_CHNORDER.
Parameters
wrchplayback channel (optional; may be NULL)
rdchrecording channel (optional; may be NULL)
mapchannel map (result will be stored there)
Return values
EINVALOperation not yet supported.

Definition at line 3200 of file dsp.c.

References CHN_LOCK, chn_oss_getorder(), and CHN_UNLOCK.

Referenced by dsp_ioctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_oss_policy()

static int dsp_oss_policy ( struct pcm_channel wrch,
struct pcm_channel rdch,
int  policy 
)
static

Handler for SNDCTL_DSP_POLICY.

The SNDCTL_DSP_POLICY ioctl is a simpler interface to control fragment size and count like with SNDCTL_DSP_SETFRAGMENT. Instead of the user specifying those two parameters, s/he simply selects a number from 0..10 which corresponds to a buffer size. Smaller numbers request smaller buffers with lower latencies (at greater overhead from more frequent interrupts), while greater numbers behave in the opposite manner.

The 4Front spec states that a value of 5 should be the default. However, this implementation deviates slightly by using a linear scale without consulting drivers. I.e., even though drivers may have different default buffer sizes, a policy argument of 5 will have the same result across all drivers.

See http://manuals.opensound.com/developer/SNDCTL_DSP_POLICY.html for more information.

Todo:
When SNDCTL_DSP_COOKEDMODE is supported, it'll be necessary to work with hardware drivers directly.
Note
PCM channel arguments must not be locked by caller.
Parameters
wrchPointer to opened playback channel (optional; may be NULL)
rdch" recording channel (optional; may be NULL)
policyInteger from [0:10]
Return values
0constant (for now)

Definition at line 3095 of file dsp.c.

References CHN_LOCK, CHN_POLICY_MAX, chn_setlatency(), and CHN_UNLOCK.

Referenced by dsp_ioctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_oss_setchnorder()

static int dsp_oss_setchnorder ( struct pcm_channel wrch,
struct pcm_channel rdch,
unsigned long long *  map 
)
static

Specify channel interleaving order.

This is the handler for SNDCTL_DSP_SET_CHNORDER.

Note
As the ioctl definition is still under construction, FreeBSD does not currently support SNDCTL_DSP_SET_CHNORDER.
Parameters
wrchplayback channel (optional; may be NULL)
rdchrecording channel (optional; may be NULL)
mapchannel map
Return values
EINVALOperation not yet supported.

Definition at line 3231 of file dsp.c.

References CHN_LOCK, chn_oss_setorder(), and CHN_UNLOCK.

Referenced by dsp_ioctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_oss_syncgroup()

static int dsp_oss_syncgroup ( struct pcm_channel wrch,
struct pcm_channel rdch,
oss_syncgroup *  group 
)
static

Assigns a PCM channel to a sync group.

Sync groups are used to enable audio operations on multiple devices simultaneously. They may be used with any number of devices and may span across applications. Devices are added to groups with the SNDCTL_DSP_SYNCGROUP ioctl, and operations are triggered with the SNDCTL_DSP_SYNCSTART ioctl.

If the id field of the group parameter is set to zero, then a new sync group is created. Otherwise, wrch and rdch (if set) are added to the group specified.

Todo:
As far as memory allocation, should we assume that things are okay and allocate with M_WAITOK before acquiring channel locks, freeing later if not?
Parameters
wrchoutput channel associated w/ device (if any)
rdchinput channel associated w/ device (if any)
groupSync group parameters
Return values
0success
non-zeroerror to be propagated upstream

Definition at line 2814 of file dsp.c.

References pcmchan_syncmember::ch, chn_abort(), CHN_F_NOTRIGGER, CHN_LOCK, chn_syncdestroy(), CHN_UNLOCK, pcm_channel::flags, free, pcmchan_syncgroup::id, pcmchan_syncmember::parent, PCM_SG_LOCK, PCM_SG_UNLOCK, pcmsg_unrhdr, pcm_channel::sm, and snd_pcm_syncgroups.

Referenced by dsp_ioctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_oss_syncstart()

static int dsp_oss_syncstart ( int  sg_id)
static

Launch a sync group into action.

Sync groups are established via SNDCTL_DSP_SYNCGROUP. This function iterates over all members, triggering them along the way.

Note
Caller must not hold any channel locks.
Parameters
sg_idsync group identifier
Return values
0success
non-zeroerror worthy of propagating upstream to user
Todo:
Is PRIBIO correct/

Definition at line 2973 of file dsp.c.

References c, pcmchan_syncmember::ch, chn_start(), CHN_TRYLOCK, CHN_UNLOCK, pcm_channel::flags, free, pcmchan_syncgroup::id, PCM_SG_LOCK, PCM_SG_UNLOCK, pcmsg_unrhdr, pcm_channel::sm, snd_pcm_syncgroups, and snd_pcm_syncgroups_mtx.

Referenced by dsp_ioctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_poll()

static int dsp_poll ( struct cdev *  i_dev,
int  events,
struct thread *  td 
)
static

Definition at line 2200 of file dsp.c.

References CHN_F_DEAD, chn_poll(), dsp_get_info(), DSP_REGISTERED, pcm_channel::flags, getchns(), PCM_DETACHING, PCM_GIANT_ENTER, PCM_GIANT_LEAVE, relchns(), SD_F_PRIO_RD, and SD_F_PRIO_WR.

Here is the call graph for this function:

◆ dsp_read()

static int dsp_read ( struct cdev *  i_dev,
struct uio *  buf,
int  flag 
)
static

Definition at line 895 of file dsp.c.

References buf, and dsp_io_ops().

Here is the call graph for this function:

◆ dsp_set_flags()

static void dsp_set_flags ( struct cdev *  dev,
uint32_t  flags 
)
static

Definition at line 135 of file dsp.c.

References dev, snddev_info::flags, pcm_devclass, pcm_setflags(), and PCMUNIT.

Referenced by dsp_cdevinfo_free(), dsp_ioctl(), and getchns().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_stdclone()

static int dsp_stdclone ( char *  name,
char *  namep,
char *  sep,
int  use_sep,
int *  u,
int *  c 
)
static

Definition at line 2321 of file dsp.c.

References c, dsp_cmax, dsp_umax, len, name, sep, and use_sep.

Referenced by dsp_clone().

Here is the caller graph for this function:

◆ dsp_sysinit()

static void dsp_sysinit ( void *  p)
static

Definition at line 2510 of file dsp.c.

References dsp_clone(), dsp_cmax, dsp_ehtag, dsp_umax, PCMMAXCHAN, PCMMAXUNIT, and snd_unit_init().

Here is the call graph for this function:

◆ dsp_sysuninit()

static void dsp_sysuninit ( void *  p)
static

Definition at line 2522 of file dsp.c.

References dsp_ehtag.

◆ dsp_unit2name()

char * dsp_unit2name ( char *  buf,
size_t  len,
int  unit 
)

Definition at line 2534 of file dsp.c.

References alias, buf, dsp_cdevs, len, name, sep, snd_unit2c(), snd_unit2d(), snd_unit2u(), type, and pcm_channel::unit.

Referenced by dsp_oss_audioinfo(), pcm_chn_create(), and vchan_sync().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dsp_write()

static int dsp_write ( struct cdev *  i_dev,
struct uio *  buf,
int  flag 
)
static

Definition at line 901 of file dsp.c.

References buf, and dsp_io_ops().

Here is the call graph for this function:

◆ getchns()

static int getchns ( struct cdev *  dev,
struct pcm_channel **  rdch,
struct pcm_channel **  wrch,
uint32_t  prio 
)
static

Definition at line 150 of file dsp.c.

References CHN_LOCK, dev, dsp_get_flags(), dsp_get_info(), dsp_set_flags(), pcm_channel::flags, PCM_ACQUIRE, pcm_chnref(), pcm_chnrelease(), PCM_LOCK, PCM_RDCH, PCM_REGISTERED, PCM_RELEASE, PCM_SIMPLEX, PCM_UNLOCK, PCM_WAIT, PCM_WRCH, SD_F_PRIO_RD, and SD_F_PRIO_WR.

Referenced by dsp_io_ops(), dsp_ioctl(), dsp_mmap_single(), and dsp_poll().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ relchns()

static void relchns ( struct cdev *  dev,
struct pcm_channel rdch,
struct pcm_channel wrch,
uint32_t  prio 
)
static

Definition at line 217 of file dsp.c.

References CHN_UNLOCK, SD_F_PRIO_RD, and SD_F_PRIO_WR.

Referenced by dsp_io_ops(), dsp_mmap_single(), and dsp_poll().

Here is the caller graph for this function:

◆ SND_DECLARE_FILE()

SND_DECLARE_FILE ( "$FreeBSD$"  )

◆ SYSCTL_INT() [1/2]

SYSCTL_INT ( _hw_snd  ,
OID_AUTO  ,
basename_clone  ,
CTLFLAG_RWTUN  ,
dsp_basename_clone,
,
"DSP basename cloning (0: Disable; 1: Enabled)"   
)

◆ SYSCTL_INT() [2/2]

SYSCTL_INT ( _hw_snd  ,
OID_AUTO  ,
compat_linux_mmap  ,
CTLFLAG_RWTUN  ,
dsp_mmap_allow_prot_exec,
,
"linux mmap compatibility (-1=force disable 0=auto 1=force enable)"   
)

◆ SYSINIT()

SYSINIT ( dsp_sysinit  ,
SI_SUB_DRIVERS  ,
SI_ORDER_MIDDLE  ,
dsp_sysinit  ,
NULL   
)

◆ SYSUNINIT()

SYSUNINIT ( dsp_sysuninit  ,
SI_SUB_DRIVERS  ,
SI_ORDER_MIDDLE  ,
dsp_sysuninit  ,
NULL   
)

Variable Documentation

◆ alias

char* alias

Definition at line 389 of file dsp.c.

Referenced by dsp_open(), and dsp_unit2name().

◆ dsp_basename_clone

int dsp_basename_clone = 1
static

Definition at line 53 of file dsp.c.

Referenced by dsp_clone().

◆ 

const struct { ... } dsp_cdevs[]

Referenced by dsp_clone(), dsp_open(), and dsp_unit2name().

◆ dsp_cdevsw

struct cdevsw dsp_cdevsw
Initial value:
= {
.d_version = D_VERSION,
.d_open = dsp_open,
.d_close = dsp_close,
.d_read = dsp_read,
.d_write = dsp_write,
.d_ioctl = dsp_ioctl,
.d_poll = dsp_poll,
.d_mmap = dsp_mmap,
.d_mmap_single = dsp_mmap_single,
.d_name = "dsp",
}
static d_write_t dsp_write
Definition: dsp.c:80
static d_mmap_t dsp_mmap
Definition: dsp.c:83
static d_close_t dsp_close
Definition: dsp.c:78
static d_open_t dsp_open
Definition: dsp.c:77
static d_mmap_single_t dsp_mmap_single
Definition: dsp.c:84
static d_ioctl_t dsp_ioctl
Definition: dsp.c:81
static d_read_t dsp_read
Definition: dsp.c:79
static d_poll_t dsp_poll
Definition: dsp.c:82

Definition at line 86 of file dsp.c.

Referenced by dsp_clone(), and dsp_oss_audioinfo().

◆ dsp_close

d_close_t dsp_close
static

Definition at line 78 of file dsp.c.

◆ dsp_cmax

int dsp_cmax = -1
static

Definition at line 101 of file dsp.c.

Referenced by dsp_clone(), dsp_stdclone(), and dsp_sysinit().

◆ dsp_ehtag

eventhandler_tag dsp_ehtag = NULL
static

Definition at line 99 of file dsp.c.

Referenced by dsp_sysinit(), and dsp_sysuninit().

◆ dsp_ioctl

d_ioctl_t dsp_ioctl
static

Definition at line 81 of file dsp.c.

◆ dsp_mmap

d_mmap_t dsp_mmap
static

Definition at line 83 of file dsp.c.

◆ dsp_mmap_allow_prot_exec

int dsp_mmap_allow_prot_exec = 0
static

Definition at line 48 of file dsp.c.

Referenced by dsp_mmap_single().

◆ dsp_mmap_single

d_mmap_single_t dsp_mmap_single
static

Definition at line 84 of file dsp.c.

◆ dsp_open

d_open_t dsp_open
static

Definition at line 77 of file dsp.c.

◆ dsp_poll

d_poll_t dsp_poll
static

Definition at line 82 of file dsp.c.

◆ dsp_read

d_read_t dsp_read
static

Definition at line 79 of file dsp.c.

◆ dsp_umax

int dsp_umax = -1
static

Definition at line 100 of file dsp.c.

Referenced by dsp_clone(), dsp_stdclone(), and dsp_sysinit().

◆ dsp_write

d_write_t dsp_write
static

Definition at line 80 of file dsp.c.

◆ fmt

uint32_t fmt

Definition at line 394 of file dsp.c.

Referenced by dsp_open().

◆ hw

int hw

Definition at line 391 of file dsp.c.

◆ max

◆ name

char* name

Definition at line 387 of file dsp.c.

Referenced by dsp_clone(), dsp_stdclone(), and dsp_unit2name().

◆ query

int query

Definition at line 395 of file dsp.c.

Referenced by dsp_open().

◆ sep

char* sep

Definition at line 388 of file dsp.c.

Referenced by dsp_stdclone(), and dsp_unit2name().

◆ spd

◆ type

◆ use_sep

int use_sep

Definition at line 390 of file dsp.c.

Referenced by dsp_clone(), and dsp_stdclone().

◆ volctl

int volctl

Definition at line 393 of file dsp.c.

Referenced by dsp_open().