summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorcg <cg@FreeBSD.org>2001-09-05 16:28:41 +0000
committercg <cg@FreeBSD.org>2001-09-05 16:28:41 +0000
commit9d8a805762329a53d281cceb6a882df9f8f81326 (patch)
tree9b366877ef6fe361dc6f34aa24fa1b89089581b9 /sys
parent5f2415a1e944afe0b68330f6a37b04b185af81d8 (diff)
downloadFreeBSD-src-9d8a805762329a53d281cceb6a882df9f8f81326.zip
FreeBSD-src-9d8a805762329a53d281cceb6a882df9f8f81326.tar.gz
add a method for recording of specific channels for devices with more than
one hardware record channel. new devices, /dev/dsprX.Y where X is unit number and Y is channel index.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sound/pcm/channel.c4
-rw-r--r--sys/dev/sound/pcm/channel.h1
-rw-r--r--sys/dev/sound/pcm/dsp.c35
-rw-r--r--sys/dev/sound/pcm/dsp.h4
-rw-r--r--sys/dev/sound/pcm/sound.c32
-rw-r--r--sys/dev/sound/pcm/sound.h3
6 files changed, 64 insertions, 15 deletions
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index f12571f..8cf2d88 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -279,7 +279,7 @@ chn_write(struct pcm_channel *c, struct uio *buf)
if (count <= 0) {
c->flags |= CHN_F_DEAD;
- printf("play interrupt timeout, channel dead\n", c->name);
+ printf("%s: play interrupt timeout, channel dead\n", c->name);
}
return ret;
@@ -402,7 +402,7 @@ chn_read(struct pcm_channel *c, struct uio *buf)
if (count <= 0) {
c->flags |= CHN_F_DEAD;
- printf("%s record interrupt timeout, channel dead\n", c->name);
+ printf("%s: record interrupt timeout, channel dead\n", c->name);
}
return ret;
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index 8e2454f..6743f4a 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -41,6 +41,7 @@ struct pcmchan_caps {
struct pcm_channel {
kobj_t methods;
+ int num;
pid_t pid;
int refcount;
struct pcm_feeder *feeder;
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index d7b2f21..6a4bfc6 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -199,6 +199,14 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p)
fmt = 0;
break;
+ case SND_DEV_DSPREC:
+ fmt = AFMT_U8;
+ if (mode & FWRITE) {
+ splx(s);
+ return EINVAL;
+ }
+ break;
+
default:
panic("impossible devtype %d", devtype);
}
@@ -220,7 +228,10 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p)
/* open for read */
if (rdch == NULL) {
/* not already open, try to get a channel */
- rdch = pcm_chnalloc(d, PCMDIR_REC, p->p_pid);
+ if (devtype == SND_DEV_DSPREC)
+ rdch = pcm_chnalloc(d, PCMDIR_REC, p->p_pid, PCMCHAN(i_dev));
+ else
+ rdch = pcm_chnalloc(d, PCMDIR_REC, p->p_pid, -1);
if (!rdch) {
/* no channel available, exit */
pcm_unlock(d);
@@ -240,7 +251,7 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p)
/* open for write */
if (wrch == NULL) {
/* not already open, try to get a channel */
- wrch = pcm_chnalloc(d, PCMDIR_PLAY, p->p_pid);
+ wrch = pcm_chnalloc(d, PCMDIR_PLAY, p->p_pid, -1);
if (!wrch) {
/* no channel available */
if (rdch && (flags & FREAD)) {
@@ -1036,6 +1047,15 @@ dsp_register(int unit, int channel)
}
int
+dsp_registerrec(int unit, int channel)
+{
+ make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSPREC, channel),
+ UID_ROOT, GID_WHEEL, 0666, "dspr%d.%d", unit, channel);
+
+ return 0;
+}
+
+int
dsp_unregister(int unit, int channel)
{
dev_t pdev;
@@ -1050,6 +1070,17 @@ dsp_unregister(int unit, int channel)
return 0;
}
+int
+dsp_unregisterrec(int unit, int channel)
+{
+ dev_t pdev;
+
+ pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, SND_DEV_DSPREC, channel));
+ destroy_dev(pdev);
+
+ return 0;
+}
+
#ifdef USING_DEVFS
static void
dsp_clone(void *arg, char *name, int namelen, dev_t *dev)
diff --git a/sys/dev/sound/pcm/dsp.h b/sys/dev/sound/pcm/dsp.h
index 39e8ea5..7943bec 100644
--- a/sys/dev/sound/pcm/dsp.h
+++ b/sys/dev/sound/pcm/dsp.h
@@ -27,6 +27,6 @@
*/
int dsp_register(int unit, int channel);
+int dsp_registerrec(int unit, int channel);
int dsp_unregister(int unit, int channel);
-
-
+int dsp_unregisterrec(int unit, int channel);
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index 4ad614b..f8b2592 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -41,7 +41,7 @@ struct snddev_channel {
struct snddev_info {
SLIST_HEAD(, snddev_channel) channels;
struct pcm_channel *fakechan;
- unsigned devcount, chancount, vchancount;
+ unsigned devcount, reccount, chancount, vchancount;
unsigned flags;
int inprog;
void *devinfo;
@@ -174,7 +174,7 @@ pcm_getfakechan(struct snddev_info *d)
/* return a locked channel */
struct pcm_channel *
-pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid)
+pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid, int chnum)
{
struct pcm_channel *c;
struct snddev_channel *sce;
@@ -187,9 +187,11 @@ pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid)
c = sce->channel;
CHN_LOCK(c);
if ((c->direction == direction) && !(c->flags & CHN_F_BUSY)) {
- c->flags |= CHN_F_BUSY;
- c->pid = pid;
- return c;
+ if (chnum == -1 || c->num == chnum) {
+ c->flags |= CHN_F_BUSY;
+ c->pid = pid;
+ return c;
+ }
}
CHN_UNLOCK(c);
}
@@ -203,7 +205,7 @@ pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid)
if (!SLIST_EMPTY(&c->children)) {
err = vchan_create(c);
if (!err)
- return pcm_chnalloc(d, direction, pid);
+ return pcm_chnalloc(d, direction, pid, -1);
else
device_printf(d->dev, "vchan_create(%s) == %d\n", c->name, err);
}
@@ -422,8 +424,18 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
SLIST_INSERT_AFTER(after, sce, link);
}
- if (mkdev)
+ if (ch->direction == PCMDIR_REC)
+ ch->num = d->reccount++;
+/*
+ else
+ ch->num = d->playcount++;
+*/
+
+ if (mkdev) {
dsp_register(unit, d->devcount++);
+ if (ch->direction == PCMDIR_REC)
+ dsp_registerrec(unit, ch->num);
+ }
d->chancount++;
if (ch->flags & CHN_F_VIRTUAL)
d->vchancount++;
@@ -453,8 +465,11 @@ gotit:
SLIST_REMOVE(&d->channels, sce, snddev_channel, link);
free(sce, M_DEVBUF);
- if (rmdev)
+ if (rmdev) {
dsp_unregister(unit, --d->devcount);
+ if (ch->direction == PCMDIR_REC)
+ dsp_unregisterrec(unit, --d->reccount);
+ }
snd_mtxunlock(d->lock);
return 0;
@@ -552,6 +567,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
d->dev = dev;
d->devinfo = devinfo;
d->devcount = 0;
+ d->reccount = 0;
d->chancount = 0;
d->vchancount = 0;
d->inprog = 0;
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 6cc6371..751b848 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -191,6 +191,7 @@ int fkchan_kill(struct pcm_channel *c);
#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
#define SND_DEV_PSS SND_DEV_SNDPROC /* ? */
#define SND_DEV_NORESET 10
+#define SND_DEV_DSPREC 11 /* recording channels */
#define DSP_DEFAULT_SPEED 8000
@@ -220,7 +221,7 @@ struct sysctl_oid *snd_sysctl_tree_top(device_t dev);
void pcm_lock(struct snddev_info *d);
void pcm_unlock(struct snddev_info *d);
struct pcm_channel *pcm_getfakechan(struct snddev_info *d);
-struct pcm_channel *pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid);
+struct pcm_channel *pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid, int chnum);
int pcm_chnrelease(struct pcm_channel *c);
int pcm_chnref(struct pcm_channel *c, int ref);
int pcm_inprog(struct snddev_info *d, int delta);
OpenPOWER on IntegriCloud