Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115840437
D47199.id145348.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D47199.id145348.diff
View Options
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -260,6 +260,7 @@
int chn_flush(struct pcm_channel *c);
int chn_poll(struct pcm_channel *c, int ev, struct thread *td);
+char *chn_mkname(char *buf, size_t len, struct pcm_channel *c);
struct pcm_channel *chn_init(struct snddev_info *d, struct pcm_channel *parent,
kobj_class_t cls, int dir, void *devinfo);
void chn_kill(struct pcm_channel *c);
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -1161,13 +1161,13 @@
chn_getunr(struct snddev_info *d, int type)
{
switch (type) {
- case SND_DEV_DSPHW_PLAY:
+ case PCMDIR_PLAY:
return (d->p_unr);
- case SND_DEV_DSPHW_VPLAY:
+ case PCMDIR_PLAY_VIRTUAL:
return (d->vp_unr);
- case SND_DEV_DSPHW_REC:
+ case PCMDIR_REC:
return (d->r_unr);
- case SND_DEV_DSPHW_VREC:
+ case PCMDIR_REC_VIRTUAL:
return (d->vr_unr);
default:
__assert_unreachable();
@@ -1175,6 +1175,37 @@
}
+char *
+chn_mkname(char *buf, size_t len, struct pcm_channel *c)
+{
+ const char *str;
+
+ KASSERT(buf != NULL && len != 0,
+ ("%s(): bogus buf=%p len=%lu", __func__, buf, len));
+
+ switch (c->type) {
+ case PCMDIR_PLAY:
+ str = "play";
+ break;
+ case PCMDIR_PLAY_VIRTUAL:
+ str = "virtual_play";
+ break;
+ case PCMDIR_REC:
+ str = "record";
+ break;
+ case PCMDIR_REC_VIRTUAL:
+ str = "virtual_record";
+ break;
+ default:
+ __assert_unreachable();
+ }
+
+ snprintf(buf, len, "dsp%d.%s.%d",
+ device_get_unit(c->dev), str, c->unit);
+
+ return (buf);
+}
+
struct pcm_channel *
chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
int dir, void *devinfo)
@@ -1183,27 +1214,19 @@
struct feeder_class *fc;
struct snd_dbuf *b, *bs;
char buf[CHN_NAMELEN];
- int i, direction, type;
+ int i, direction;
PCM_BUSYASSERT(d);
PCM_LOCKASSERT(d);
switch (dir) {
- case PCMDIR_PLAY:
- direction = PCMDIR_PLAY;
- type = SND_DEV_DSPHW_PLAY;
- break;
+ case PCMDIR_PLAY: /* FALLTHROUGH */
case PCMDIR_PLAY_VIRTUAL:
direction = PCMDIR_PLAY;
- type = SND_DEV_DSPHW_VPLAY;
- break;
- case PCMDIR_REC:
- direction = PCMDIR_REC;
- type = SND_DEV_DSPHW_REC;
break;
+ case PCMDIR_REC: /* FALLTHROUGH */
case PCMDIR_REC_VIRTUAL:
direction = PCMDIR_REC;
- type = SND_DEV_DSPHW_VREC;
break;
default:
device_printf(d->dev,
@@ -1222,7 +1245,7 @@
CHN_INIT(c, children);
CHN_INIT(c, children.busy);
c->direction = direction;
- c->type = type;
+ c->type = dir;
c->unit = alloc_unr(chn_getunr(d, c->type));
c->format = SND_FORMAT(AFMT_U8, 1, 0);
c->speed = DSP_DEFAULT_SPEED;
@@ -1234,8 +1257,7 @@
c->parentchannel = parent;
c->dev = d->dev;
c->trigger = PCMTRIG_STOP;
-
- strlcpy(c->name, dsp_unit2name(buf, sizeof(buf), c), sizeof(c->name));
+ strlcpy(c->name, chn_mkname(buf, sizeof(buf), c), sizeof(c->name));
c->matrix = *feeder_matrix_id_map(SND_CHN_MATRIX_1_0);
c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL;
@@ -1303,16 +1325,16 @@
CHN_INSERT_SORT_ASCEND(d, c, channels.pcm);
switch (c->type) {
- case SND_DEV_DSPHW_PLAY:
+ case PCMDIR_PLAY:
d->playcount++;
break;
- case SND_DEV_DSPHW_VPLAY:
+ case PCMDIR_PLAY_VIRTUAL:
d->pvchancount++;
break;
- case SND_DEV_DSPHW_REC:
+ case PCMDIR_REC:
d->reccount++;
break;
- case SND_DEV_DSPHW_VREC:
+ case PCMDIR_REC_VIRTUAL:
d->rvchancount++;
break;
default:
@@ -1354,16 +1376,16 @@
CHN_REMOVE(d, c, channels.pcm);
switch (c->type) {
- case SND_DEV_DSPHW_PLAY:
+ case PCMDIR_PLAY:
d->playcount--;
break;
- case SND_DEV_DSPHW_VPLAY:
+ case PCMDIR_PLAY_VIRTUAL:
d->pvchancount--;
break;
- case SND_DEV_DSPHW_REC:
+ case PCMDIR_REC:
d->reccount--;
break;
- case SND_DEV_DSPHW_VREC:
+ case PCMDIR_REC_VIRTUAL:
d->rvchancount--;
break;
default:
diff --git a/sys/dev/sound/pcm/dsp.h b/sys/dev/sound/pcm/dsp.h
--- a/sys/dev/sound/pcm/dsp.h
+++ b/sys/dev/sound/pcm/dsp.h
@@ -35,7 +35,6 @@
int dsp_make_dev(device_t);
void dsp_destroy_dev(device_t);
-char *dsp_unit2name(char *, size_t, struct pcm_channel *);
int dsp_oss_audioinfo(struct cdev *, oss_audioinfo *, bool);
int dsp_oss_engineinfo(struct cdev *, oss_audioinfo *);
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -164,25 +164,6 @@
#define DSP_F_READ(x) ((x) & FREAD)
#define DSP_F_WRITE(x) ((x) & FWRITE)
-static const struct {
- int type;
- char *name;
- char *sep;
- char *alias;
-} dsp_cdevs[] = {
- { SND_DEV_DSP, "dsp", ".", NULL },
- { SND_DEV_DSPHW_PLAY, "dsp", ".play.", NULL },
- { SND_DEV_DSPHW_VPLAY, "dsp", ".virtual_play.", NULL },
- { SND_DEV_DSPHW_REC, "dsp", ".record.", NULL },
- { SND_DEV_DSPHW_VREC, "dsp", ".virtual_record.", NULL },
- /* Low priority, OSSv4 aliases. */
- { SND_DEV_DSP, "dsp_ac3", ".", "dsp" },
- { SND_DEV_DSP, "dsp_mmap", ".", "dsp" },
- { SND_DEV_DSP, "dsp_multich", ".", "dsp" },
- { SND_DEV_DSP, "dsp_spdifout", ".", "dsp" },
- { SND_DEV_DSP, "dsp_spdifin", ".", "dsp" },
-};
-
static void
dsp_close(void *data)
{
@@ -1941,20 +1922,26 @@
return (0);
}
+static const char *dsp_aliases[] = {
+ "dsp_ac3",
+ "dsp_mmap",
+ "dsp_multich",
+ "dsp_spdifout",
+ "dsp_spdifin",
+};
+
static void
dsp_clone(void *arg, struct ucred *cred, char *name, int namelen,
struct cdev **dev)
{
struct snddev_info *d;
size_t i;
-
if (*dev != NULL)
return;
if (strcmp(name, "dsp") == 0 && dsp_basename_clone)
goto found;
- for (i = 0; i < nitems(dsp_cdevs); i++) {
- if (dsp_cdevs[i].alias != NULL &&
- strcmp(name, dsp_cdevs[i].name) == 0)
+ for (i = 0; i < nitems(dsp_aliases); i++) {
+ if (strcmp(name, dsp_aliases[i]) == 0)
goto found;
}
return;
@@ -1994,26 +1981,6 @@
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, struct pcm_channel *ch)
-{
- size_t i;
-
- KASSERT(buf != NULL && len != 0,
- ("bogus buf=%p len=%ju", buf, (uintmax_t)len));
-
- for (i = 0; i < nitems(dsp_cdevs); i++) {
- if (ch->type != dsp_cdevs[i].type || dsp_cdevs[i].alias != NULL)
- continue;
- snprintf(buf, len, "%s%d%s%d",
- dsp_cdevs[i].name, device_get_unit(ch->dev),
- dsp_cdevs[i].sep, ch->unit);
- return (buf);
- }
-
- return (NULL);
-}
-
static void
dsp_oss_audioinfo_unavail(oss_audioinfo *ai, int unit)
{
@@ -2233,7 +2200,6 @@
struct snddev_info *d;
uint32_t fmts;
int i, nchan, *rates, minch, maxch, unit;
- char *devname, buf[CHN_NAMELEN];
/*
* If probing the device that received the ioctl, make sure it's a
@@ -2244,9 +2210,7 @@
return (EINVAL);
ch = NULL;
- devname = NULL;
nchan = 0;
- bzero(buf, sizeof(buf));
/*
* Search for the requested audio device (channel). Start by
@@ -2267,147 +2231,142 @@
CHN_FOREACH(ch, d, channels.pcm) {
CHN_UNLOCKASSERT(ch);
CHN_LOCK(ch);
- if (ai->dev == -1) {
- if (devfs_foreach_cdevpriv(i_dev,
- dsp_oss_engineinfo_cb, ch) != 0) {
- devname = dsp_unit2name(buf,
- sizeof(buf), ch);
- }
- } else if (ai->dev == nchan)
- devname = dsp_unit2name(buf, sizeof(buf), ch);
- if (devname != NULL)
+ if ((ai->dev == -1 && devfs_foreach_cdevpriv(
+ i_dev, dsp_oss_engineinfo_cb, ch) != 0) ||
+ ai->dev == nchan)
break;
CHN_UNLOCK(ch);
++nchan;
}
- if (devname != NULL) {
- /*
- * At this point, the following synchronization stuff
- * has happened:
- * - a specific PCM device is locked.
- * - a specific audio channel has been locked, so be
- * sure to unlock when exiting;
- */
+ if (ch == NULL) {
+ PCM_UNLOCK(d);
+ continue;
+ }
- caps = chn_getcaps(ch);
+ /*
+ * At this point, the following synchronization stuff
+ * has happened:
+ * - a specific PCM device is locked.
+ * - a specific audio channel has been locked, so be
+ * sure to unlock when exiting;
+ */
- /*
- * With all handles collected, zero out the user's
- * container and begin filling in its fields.
- */
- bzero((void *)ai, sizeof(oss_audioinfo));
+ caps = chn_getcaps(ch);
- ai->dev = nchan;
- strlcpy(ai->name, ch->name, sizeof(ai->name));
+ /*
+ * With all handles collected, zero out the user's
+ * container and begin filling in its fields.
+ */
+ bzero((void *)ai, sizeof(oss_audioinfo));
- if ((ch->flags & CHN_F_BUSY) == 0)
- ai->busy = 0;
- else
- ai->busy = (ch->direction == PCMDIR_PLAY) ? OPEN_WRITE : OPEN_READ;
+ ai->dev = nchan;
+ strlcpy(ai->name, ch->name, sizeof(ai->name));
- ai->pid = ch->pid;
- strlcpy(ai->cmd, ch->comm, sizeof(ai->cmd));
+ if ((ch->flags & CHN_F_BUSY) == 0)
+ ai->busy = 0;
+ else
+ ai->busy = (ch->direction == PCMDIR_PLAY) ? OPEN_WRITE : OPEN_READ;
- /*
- * These flags stolen from SNDCTL_DSP_GETCAPS handler.
- * Note, however, that a single channel operates in
- * only one direction, so PCM_CAP_DUPLEX is out.
- */
- /**
- * @todo @c SNDCTL_AUDIOINFO::caps - Make drivers keep
- * these in pcmchan::caps?
- */
- ai->caps = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER |
- ((ch->flags & CHN_F_VIRTUAL) ? PCM_CAP_VIRTUAL : 0) |
- ((ch->direction == PCMDIR_PLAY) ? PCM_CAP_OUTPUT : PCM_CAP_INPUT);
+ ai->pid = ch->pid;
+ strlcpy(ai->cmd, ch->comm, sizeof(ai->cmd));
- /*
- * Collect formats supported @b natively by the
- * device. Also determine min/max channels.
- */
- minch = INT_MAX;
- maxch = 0;
- fmts = 0;
- for (i = 0; caps->fmtlist[i]; i++) {
- fmts |= AFMT_ENCODING(caps->fmtlist[i]);
- minch = min(AFMT_CHANNEL(caps->fmtlist[i]), minch);
- maxch = max(AFMT_CHANNEL(caps->fmtlist[i]), maxch);
- }
+ /*
+ * These flags stolen from SNDCTL_DSP_GETCAPS handler.
+ * Note, however, that a single channel operates in
+ * only one direction, so PCM_CAP_DUPLEX is out.
+ */
+ /**
+ * @todo @c SNDCTL_AUDIOINFO::caps - Make drivers keep
+ * these in pcmchan::caps?
+ */
+ ai->caps = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER |
+ ((ch->flags & CHN_F_VIRTUAL) ? PCM_CAP_VIRTUAL : 0) |
+ ((ch->direction == PCMDIR_PLAY) ? PCM_CAP_OUTPUT : PCM_CAP_INPUT);
- if (ch->direction == PCMDIR_PLAY)
- ai->oformats = fmts;
- else
- ai->iformats = fmts;
-
- /**
- * @note
- * @c magic - OSSv4 docs: "Reserved for internal use
- * by OSS."
- *
- * @par
- * @c 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."
- */
- ai->card_number = unit;
- /**
- * @todo @c song_name - depends first on
- * SNDCTL_[GS]ETSONG @todo @c label - depends
- * on SNDCTL_[GS]ETLABEL
- * @todo @c port_number - routing information?
- */
- ai->port_number = unit;
- ai->mixer_dev = (d->mixer_dev != NULL) ? unit : -1;
- /**
- * @note
- * @c legacy_device - OSSv4 docs: "Obsolete."
- */
- ai->legacy_device = unit;
- snprintf(ai->devnode, sizeof(ai->devnode), "/dev/dsp%d", unit);
- ai->enabled = device_is_attached(d->dev) ? 1 : 0;
- /**
- * @note
- * @c flags - OSSv4 docs: "Reserved for future use."
- *
- * @note
- * @c binding - OSSv4 docs: "Reserved for future use."
- *
- * @todo @c handle - haven't decided how to generate
- * this yet; bus, vendor, device IDs?
- */
+ /*
+ * Collect formats supported @b natively by the
+ * device. Also determine min/max channels.
+ */
+ minch = INT_MAX;
+ maxch = 0;
+ fmts = 0;
+ for (i = 0; caps->fmtlist[i]; i++) {
+ fmts |= AFMT_ENCODING(caps->fmtlist[i]);
+ minch = min(AFMT_CHANNEL(caps->fmtlist[i]), minch);
+ maxch = max(AFMT_CHANNEL(caps->fmtlist[i]), maxch);
+ }
- if ((ch->flags & CHN_F_EXCLUSIVE) ||
- (pcm_getflags(d->dev) & SD_F_BITPERFECT)) {
- ai->min_rate = caps->minspeed;
- ai->max_rate = caps->maxspeed;
- } else {
- ai->min_rate = feeder_rate_min;
- ai->max_rate = feeder_rate_max;
- }
+ if (ch->direction == PCMDIR_PLAY)
+ ai->oformats = fmts;
+ else
+ ai->iformats = fmts;
+
+ /**
+ * @note
+ * @c magic - OSSv4 docs: "Reserved for internal use
+ * by OSS."
+ *
+ * @par
+ * @c 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."
+ */
+ ai->card_number = unit;
+ /**
+ * @todo @c song_name - depends first on
+ * SNDCTL_[GS]ETSONG @todo @c label - depends
+ * on SNDCTL_[GS]ETLABEL
+ * @todo @c port_number - routing information?
+ */
+ ai->port_number = unit;
+ ai->mixer_dev = (d->mixer_dev != NULL) ? unit : -1;
+ /**
+ * @note
+ * @c legacy_device - OSSv4 docs: "Obsolete."
+ */
+ ai->legacy_device = unit;
+ snprintf(ai->devnode, sizeof(ai->devnode), "/dev/dsp%d", unit);
+ ai->enabled = device_is_attached(d->dev) ? 1 : 0;
+ /**
+ * @note
+ * @c flags - OSSv4 docs: "Reserved for future use."
+ *
+ * @note
+ * @c binding - OSSv4 docs: "Reserved for future use."
+ *
+ * @todo @c handle - haven't decided how to generate
+ * this yet; bus, vendor, device IDs?
+ */
- ai->min_channels = minch;
- ai->max_channels = maxch;
+ if ((ch->flags & CHN_F_EXCLUSIVE) ||
+ (pcm_getflags(d->dev) & SD_F_BITPERFECT)) {
+ ai->min_rate = caps->minspeed;
+ ai->max_rate = caps->maxspeed;
+ } else {
+ ai->min_rate = feeder_rate_min;
+ ai->max_rate = feeder_rate_max;
+ }
- ai->nrates = chn_getrates(ch, &rates);
- if (ai->nrates > OSS_MAX_SAMPLE_RATES)
- ai->nrates = OSS_MAX_SAMPLE_RATES;
+ ai->min_channels = minch;
+ ai->max_channels = maxch;
- for (i = 0; i < ai->nrates; i++)
- ai->rates[i] = rates[i];
-
- ai->next_play_engine = 0;
- ai->next_rec_engine = 0;
+ ai->nrates = chn_getrates(ch, &rates);
+ if (ai->nrates > OSS_MAX_SAMPLE_RATES)
+ ai->nrates = OSS_MAX_SAMPLE_RATES;
- CHN_UNLOCK(ch);
- }
+ for (i = 0; i < ai->nrates; i++)
+ ai->rates[i] = rates[i];
+
+ ai->next_play_engine = 0;
+ ai->next_rec_engine = 0;
+ CHN_UNLOCK(ch);
PCM_UNLOCK(d);
- if (devname != NULL)
- return (0);
+ return (0);
}
/* Exhausted the search -- nothing is locked, so return. */
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -225,10 +225,6 @@
SND_DEV_MIDIN, /* Raw midi access */
SND_DEV_DSP, /* Digitized voice /dev/dsp */
SND_DEV_STATUS, /* /dev/sndstat */
- SND_DEV_DSPHW_PLAY, /* specific playback channel */
- SND_DEV_DSPHW_VPLAY, /* specific virtual playback channel */
- SND_DEV_DSPHW_REC, /* specific record channel */
- SND_DEV_DSPHW_VREC, /* specific virtual record channel */
};
#define DSP_DEFAULT_SPEED 8000
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -886,14 +886,9 @@
c->flags |= CHN_F_DIRTY;
#ifdef SND_DEBUG
- if (snd_passthrough_verbose != 0) {
- char *devname, buf[CHN_NAMELEN];
-
- devname = dsp_unit2name(buf, sizeof(buf), c);
- device_printf(c->dev,
- "%s(%s/%s) %s() -> re-sync err=%d\n",
- __func__, (devname != NULL) ? devname : "dspX", c->comm,
- caller, ret);
+ if (snd_passthrough_verbose) {
+ device_printf(c->dev, "%s(%s/%s) %s() -> re-sync err=%d\n",
+ __func__, c->name, c->comm, caller, ret);
}
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 30, 10:02 AM (11 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17855683
Default Alt Text
D47199.id145348.diff (15 KB)
Attached To
Mode
D47199: sound: Untangle dsp_cdevs[] and dsp_unit2name() confusion
Attached
Detach File
Event Timeline
Log In to Comment