Import some new constants and structures fields from OSSv4.

Implement some OSSv4 ioctls to make ossinfo tool work and print
something reasonable.
This commit is contained in:
Alexander Motin 2009-01-10 18:19:22 +00:00
parent 5f3fed855c
commit 52f6e09e09
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=187030
5 changed files with 161 additions and 44 deletions

View File

@ -814,7 +814,12 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
case SNDCTL_SYSINFO:
sound_oss_sysinfo((oss_sysinfo *)arg);
break;
case SNDCTL_CARDINFO:
ret = sound_oss_card_info((oss_card_info *)arg);
break;
case SNDCTL_AUDIOINFO:
case SNDCTL_AUDIOINFO_EX:
case SNDCTL_ENGINEINFO:
ret = dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg);
break;
case SNDCTL_MIXERINFO:
@ -1370,9 +1375,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
case SNDCTL_DSP_GETCAPS:
pcm_lock(d);
*arg_i = DSP_CAP_REALTIME | DSP_CAP_MMAP | DSP_CAP_TRIGGER;
*arg_i = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER;
if (rdch && wrch && !(dsp_get_flags(i_dev) & SD_F_SIMPLEX))
*arg_i |= DSP_CAP_DUPLEX;
*arg_i |= PCM_CAP_DUPLEX;
pcm_unlock(d);
break;
@ -1769,18 +1774,6 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread *
ret = dsp_oss_setname(wrch, rdch, (oss_longname_t *)arg);
break;
#if 0
/**
* @note The SNDCTL_CARDINFO ioctl was omitted per 4Front developer
* documentation. "The usability of this call is very limited. It's
* provided only for completeness of the API. OSS API doesn't have
* any concept of card. Any information returned by this ioctl calld
* is reserved exclusively for the utility programs included in the
* OSS package. Applications should not try to use for this
* information in any ways."
*/
case SNDCTL_CARDINFO:
ret = EINVAL;
break;
/**
* @note The S/PDIF interface ioctls, @c SNDCTL_DSP_READCTL and
* @c SNDCTL_DSP_WRITECTL have been omitted at the suggestion of
@ -2282,13 +2275,14 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
/*
* These flags stolen from SNDCTL_DSP_GETCAPS handler.
* Note, however, that a single channel operates in
* only one direction, so DSP_CAP_DUPLEX is out.
* only one direction, so PCM_CAP_DUPLEX is out.
*/
/**
* @todo @c SNDCTL_AUDIOINFO::caps - Make drivers keep
* these in pcmchan::caps?
*/
ai->caps = DSP_CAP_REALTIME | DSP_CAP_MMAP | DSP_CAP_TRIGGER;
ai->caps = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER |
((ch->direction == PCMDIR_PLAY) ? PCM_CAP_OUTPUT : PCM_CAP_INPUT);
/*
* Collect formats supported @b natively by the
@ -2369,7 +2363,11 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai)
for (i = 0; i < ai->nrates; i++)
ai->rates[i] = rates[i];
ai->next_play_engine = 0;
ai->next_rec_engine = 0;
printf("flags: %08x %d\n", ch->flags, ai->busy);
CHN_UNLOCK(ch);
}

View File

@ -1022,6 +1022,27 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
int ret, *arg_i = (int *)arg;
int v = -1, j = cmd & 0xff;
/*
* Certain ioctls may be made on any type of device (audio, mixer,
* and MIDI). Handle those special cases here.
*/
if (IOCGROUP(cmd) == 'X') {
switch (cmd) {
case SNDCTL_SYSINFO:
sound_oss_sysinfo((oss_sysinfo *)arg);
return (0);
case SNDCTL_CARDINFO:
return (sound_oss_card_info((oss_card_info *)arg));
case SNDCTL_AUDIOINFO:
case SNDCTL_AUDIOINFO_EX:
case SNDCTL_ENGINEINFO:
return (dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg));
case SNDCTL_MIXERINFO:
return (mixer_oss_mixerinfo(i_dev, (oss_mixerinfo *)arg));
}
return (ENXIO);
}
m = i_dev->si_drv1;
if (m == NULL)
@ -1033,11 +1054,6 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
return (EBADF);
}
if (cmd == SNDCTL_MIXERINFO) {
snd_mtxunlock(m->lock);
return (mixer_oss_mixerinfo(i_dev, (oss_mixerinfo *)arg));
}
if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) {
if (j == SOUND_MIXER_RECSRC)
ret = mixer_setrecsrc(m, *arg_i);
@ -1075,15 +1091,6 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
switch (cmd) {
/** @todo Double check return values, error codes. */
case SNDCTL_SYSINFO:
snd_mtxunlock(m->lock);
sound_oss_sysinfo((oss_sysinfo *)arg);
return (ret);
break;
case SNDCTL_AUDIOINFO:
snd_mtxunlock(m->lock);
return (dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg));
break;
case SNDCTL_DSP_GET_RECSRC_NAMES:
bcopy((void *)&m->enuminfo, arg, sizeof(oss_mixer_enuminfo));
break;

View File

@ -1493,6 +1493,38 @@ sound_oss_sysinfo(oss_sysinfo *si)
si->filler[i] = -1;
}
int
sound_oss_card_info(oss_card_info *si)
{
struct snddev_info *d;
int i, ncards;
ncards = 0;
for (i = 0; pcm_devclass != NULL &&
i < devclass_get_maxunit(pcm_devclass); i++) {
d = devclass_get_softc(pcm_devclass, i);
if (!PCM_REGISTERED(d))
continue;
if (ncards++ != si->card)
continue;
mtx_assert(d->lock, MA_NOTOWNED);
pcm_lock(d);
strlcpy(si->shortname, device_get_nameunit(d->dev),
sizeof(si->shortname));
strlcpy(si->longname, device_get_desc(d->dev),
sizeof(si->longname));
strlcpy(si->hw_info, d->status, sizeof(si->hw_info));
si->intr_count = si->ack_count = 0;
pcm_unlock(d);
return (0);
}
return (ENXIO);
}
/************************************************************************/
static int

View File

@ -601,6 +601,7 @@ struct snddev_info {
};
void sound_oss_sysinfo(oss_sysinfo *);
int sound_oss_card_info(oss_card_info *);
#ifdef PCM_DEBUG_MTX
#define pcm_lock(d) mtx_lock(((struct snddev_info *)(d))->lock)

View File

@ -801,18 +801,91 @@ typedef struct audio_buf_info {
#define SNDCTL_DSP_NONBLOCK _IO ('P',14)
#define SNDCTL_DSP_GETCAPS _IOR ('P',15, int)
#define DSP_CAP_REVISION 0x000000ff /* revision level (0 to 255) */
#define DSP_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */
#define DSP_CAP_REALTIME 0x00000200 /* Real time capability */
#define DSP_CAP_BATCH 0x00000400
/*
* Device has some kind of internal buffers which may
* cause some delays and decrease precision of timing
*/
#define DSP_CAP_COPROC 0x00000800
/* Has a coprocessor, sometimes it's a DSP but usually not */
#define DSP_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */
#define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */
# define PCM_CAP_REVISION 0x000000ff /* Bits for revision level (0 to 255) */
# define PCM_CAP_DUPLEX 0x00000100 /* Full duplex record/playback */
# define PCM_CAP_REALTIME 0x00000200 /* Not in use */
# define PCM_CAP_BATCH 0x00000400 /* Device has some kind of */
/* internal buffers which may */
/* cause some delays and */
/* decrease precision of timing */
# define PCM_CAP_COPROC 0x00000800 /* Has a coprocessor */
/* Sometimes it's a DSP */
/* but usually not */
# define PCM_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */
# define PCM_CAP_MMAP 0x00002000 /* Supports mmap() */
# define PCM_CAP_MULTI 0x00004000 /* Supports multiple open */
# define PCM_CAP_BIND 0x00008000 /* Supports binding to front/rear/center/lfe */
# define PCM_CAP_INPUT 0x00010000 /* Supports recording */
# define PCM_CAP_OUTPUT 0x00020000 /* Supports playback */
# define PCM_CAP_VIRTUAL 0x00040000 /* Virtual device */
/* 0x00040000 and 0x00080000 reserved for future use */
/* Analog/digital control capabilities */
# define PCM_CAP_ANALOGOUT 0x00100000
# define PCM_CAP_ANALOGIN 0x00200000
# define PCM_CAP_DIGITALOUT 0x00400000
# define PCM_CAP_DIGITALIN 0x00800000
# define PCM_CAP_ADMASK 0x00f00000
/*
* NOTE! (capabilities & PCM_CAP_ADMASK)==0 means just that the
* digital/analog interface control features are not supported by the
* device/driver. However the device still supports analog, digital or
* both inputs/outputs (depending on the device). See the OSS Programmer's
* Guide for full details.
*/
# define PCM_CAP_SPECIAL 0x01000000 /* Not for ordinary "multimedia" use */
# define PCM_CAP_SHADOW 0x00000000 /* OBSOLETE */
/*
* Preferred channel usage. These bits can be used to
* give recommendations to the application. Used by few drivers.
* For example if ((caps & DSP_CH_MASK) == DSP_CH_MONO) means that
* the device works best in mono mode. However it doesn't necessarily mean
* that the device cannot be used in stereo. These bits should only be used
* by special applications such as multi track hard disk recorders to find
* out the initial setup. However the user should be able to override this
* selection.
*
* To find out which modes are actually supported the application should
* try to select them using SNDCTL_DSP_CHANNELS.
*/
# define DSP_CH_MASK 0x06000000 /* Mask */
# define DSP_CH_ANY 0x00000000 /* No preferred mode */
# define DSP_CH_MONO 0x02000000
# define DSP_CH_STEREO 0x04000000
# define DSP_CH_MULTI 0x06000000 /* More than two channels */
# define PCM_CAP_HIDDEN 0x08000000 /* Hidden device */
# define PCM_CAP_FREERATE 0x10000000
# define PCM_CAP_MODEM 0x20000000 /* Modem device */
# define PCM_CAP_DEFAULT 0x40000000 /* "Default" device */
/*
* The PCM_CAP_* capability names were known as DSP_CAP_* prior OSS 4.0
* so it's necessary to define the older names too.
*/
#define DSP_CAP_ADMASK PCM_CAP_ADMASK
#define DSP_CAP_ANALOGIN PCM_CAP_ANALOGIN
#define DSP_CAP_ANALOGOUT PCM_CAP_ANALOGOUT
#define DSP_CAP_BATCH PCM_CAP_BATCH
#define DSP_CAP_BIND PCM_CAP_BIND
#define DSP_CAP_COPROC PCM_CAP_COPROC
#define DSP_CAP_DEFAULT PCM_CAP_DEFAULT
#define DSP_CAP_DIGITALIN PCM_CAP_DIGITALIN
#define DSP_CAP_DIGITALOUT PCM_CAP_DIGITALOUT
#define DSP_CAP_DUPLEX PCM_CAP_DUPLEX
#define DSP_CAP_FREERATE PCM_CAP_FREERATE
#define DSP_CAP_HIDDEN PCM_CAP_HIDDEN
#define DSP_CAP_INPUT PCM_CAP_INPUT
#define DSP_CAP_MMAP PCM_CAP_MMAP
#define DSP_CAP_MODEM PCM_CAP_MODEM
#define DSP_CAP_MULTI PCM_CAP_MULTI
#define DSP_CAP_OUTPUT PCM_CAP_OUTPUT
#define DSP_CAP_REALTIME PCM_CAP_REALTIME
#define DSP_CAP_REVISION PCM_CAP_REVISION
#define DSP_CAP_SHADOW PCM_CAP_SHADOW
#define DSP_CAP_TRIGGER PCM_CAP_TRIGGER
#define DSP_CAP_VIRTUAL PCM_CAP_VIRTUAL
/*
* What do these function do ?
@ -1785,7 +1858,9 @@ typedef struct oss_audioinfo
int latency; /* In usecs, -1=unknown */
oss_devnode_t devnode; /* Device special file name (inside
/dev) */
int filler[186];
int next_play_engine;
int next_rec_engine;
int filler[184];
} oss_audioinfo;
typedef struct oss_mixerinfo
@ -1851,7 +1926,9 @@ typedef struct oss_card_info
char shortname[16];
char longname[128];
int flags;
int filler[256];
char hw_info[400];
int intr_count, ack_count;
int filler[154];
} oss_card_info;
#define SNDCTL_SYSINFO _IOR ('X', 1, oss_sysinfo)
@ -1868,6 +1945,8 @@ typedef struct oss_card_info
#define SNDCTL_MIDIINFO _IOWR('X', 9, oss_midi_info)
#define SNDCTL_MIXERINFO _IOWR('X',10, oss_mixerinfo)
#define SNDCTL_CARDINFO _IOWR('X',11, oss_card_info)
#define SNDCTL_ENGINEINFO _IOWR('X',12, oss_audioinfo)
#define SNDCTL_AUDIOINFO_EX _IOWR('X',13, oss_audioinfo)
/*
* Few more "globally" available ioctl calls.