mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
add a tunable/sysctl, hw.snd.autovchans. if this is set to a value n where
n > 0, n vchans will be assigned to any devices that subsequently register with a single playback channel.
This commit is contained in:
parent
a30e186209
commit
cd9766c5f8
3 changed files with 53 additions and 4 deletions
|
|
@ -37,6 +37,8 @@ devclass_t pcm_devclass;
|
|||
int snd_unit = 0;
|
||||
TUNABLE_INT("hw.snd.unit", &snd_unit);
|
||||
#endif
|
||||
int snd_autovchans = 0;
|
||||
TUNABLE_INT("hw.snd.autovchans", &snd_autovchans);
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, snd, CTLFLAG_RD, 0, "Sound driver");
|
||||
|
||||
|
|
@ -157,7 +159,7 @@ pcm_chnref(struct pcm_channel *c, int ref)
|
|||
|
||||
#ifdef USING_DEVFS
|
||||
static int
|
||||
sysctl_hw_sndunit(SYSCTL_HANDLER_ARGS)
|
||||
sysctl_hw_snd_unit(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct snddev_info *d;
|
||||
int error, unit;
|
||||
|
|
@ -175,9 +177,26 @@ sysctl_hw_sndunit(SYSCTL_HANDLER_ARGS)
|
|||
return (error);
|
||||
}
|
||||
SYSCTL_PROC(_hw_snd, OID_AUTO, unit, CTLTYPE_INT | CTLFLAG_RW,
|
||||
0, sizeof(int), sysctl_hw_sndunit, "I", "");
|
||||
0, sizeof(int), sysctl_hw_snd_unit, "I", "");
|
||||
#endif
|
||||
|
||||
static int
|
||||
sysctl_hw_snd_autovchans(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int v, error;
|
||||
|
||||
v = snd_autovchans;
|
||||
error = sysctl_handle_int(oidp, &v, sizeof(v), req);
|
||||
if (error == 0 && req->newptr != NULL) {
|
||||
if (v < 0 || v >= SND_MAXVCHANS)
|
||||
return EINVAL;
|
||||
snd_autovchans = v;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
SYSCTL_PROC(_hw_snd, OID_AUTO, autovchans, CTLTYPE_INT | CTLFLAG_RW,
|
||||
0, sizeof(int), sysctl_hw_snd_autovchans, "I", "");
|
||||
|
||||
struct pcm_channel *
|
||||
pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, void *devinfo)
|
||||
{
|
||||
|
|
@ -296,18 +315,36 @@ int
|
|||
pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
|
||||
{
|
||||
struct snddev_info *d = device_get_softc(dev);
|
||||
struct pcm_channel *ch;
|
||||
int err;
|
||||
struct pcm_channel *ch, *child;
|
||||
struct pcmchan_children *pce;
|
||||
int i, err;
|
||||
|
||||
ch = pcm_chn_create(d, NULL, cls, dir, devinfo);
|
||||
if (!ch) {
|
||||
device_printf(d->dev, "pcm_chn_create(%s, %d, %p) failed\n", cls->name, dir, devinfo);
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
err = pcm_chn_add(d, ch);
|
||||
if (err) {
|
||||
device_printf(d->dev, "pcm_chn_add(%s) failed, err=%d\n", ch->name, err);
|
||||
pcm_chn_destroy(ch);
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((dir == PCMDIR_PLAY) && (d->flags & SD_F_AUTOVCHAN)) {
|
||||
ch->flags |= CHN_F_BUSY;
|
||||
for (i = 0; err == 0 && i < snd_autovchans; i++)
|
||||
err = vchan_create(ch);
|
||||
if (err) {
|
||||
device_printf(d->dev, "vchan_create(%d) failed, err=%d\n", i - 1, err);
|
||||
SLIST_FOREACH(pce, &ch->children, link) {
|
||||
child = pce->channel;
|
||||
vchan_destroy(child);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
@ -370,6 +407,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
|
|||
d->lock = snd_mtxcreate(device_get_nameunit(dev));
|
||||
snd_mtxlock(d->lock);
|
||||
|
||||
d->flags = 0;
|
||||
d->dev = dev;
|
||||
d->devinfo = devinfo;
|
||||
d->chancount = 0;
|
||||
|
|
@ -393,6 +431,9 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
|
|||
#endif
|
||||
if (numplay > 0)
|
||||
vchan_initsys(d);
|
||||
if (numplay == 1)
|
||||
d->flags |= SD_F_AUTOVCHAN;
|
||||
|
||||
snd_mtxunlock(d->lock);
|
||||
return 0;
|
||||
no:
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ nomenclature:
|
|||
#define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 16) | (((u) & 0x0f) << 4) | ((d) & 0x0f))
|
||||
|
||||
#define SD_F_SIMPLEX 0x00000001
|
||||
#define SD_F_AUTOVCHAN 0x00000002
|
||||
#define SD_F_PRIO_RD 0x10000000
|
||||
#define SD_F_PRIO_WR 0x20000000
|
||||
#define SD_F_PRIO_SET (SD_F_PRIO_RD | SD_F_PRIO_WR)
|
||||
|
|
@ -190,6 +191,8 @@ int fkchan_kill(struct pcm_channel *c);
|
|||
*/
|
||||
#define SND_CDEV_MAJOR 30
|
||||
|
||||
#define SND_MAXVCHANS 255
|
||||
|
||||
/*
|
||||
* Minor numbers for the sound driver.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -348,6 +348,11 @@ sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS)
|
|||
|
||||
err = sysctl_handle_int(oidp, &newcnt, sizeof(newcnt), req);
|
||||
if (err == 0 && req->newptr != NULL) {
|
||||
if (newcnt < 0 || newcnt > SND_MAXVCHANS) {
|
||||
snd_mtxunlock(d->lock);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (newcnt > cnt) {
|
||||
/* add new vchans - find a parent channel first */
|
||||
SLIST_FOREACH(sce, &d->channels, link) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue