ossaudio(3): Add an implementation of SNDCTL_CARDINFO
Correct some of the counts returned by SNDCTL_SYSINFO so this works.
This commit is contained in:
parent
7e88dcfff9
commit
2cd43b36c6
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: ossaudio.c,v 1.55 2020/10/22 19:39:48 nia Exp $ */
|
/* $NetBSD: ossaudio.c,v 1.56 2020/10/23 09:05:20 nia Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1997, 2020 The NetBSD Foundation, Inc.
|
* Copyright (c) 1997, 2020 The NetBSD Foundation, Inc.
|
||||||
@ -27,7 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: ossaudio.c,v 1.55 2020/10/22 19:39:48 nia Exp $");
|
__RCSID("$NetBSD: ossaudio.c,v 1.56 2020/10/23 09:05:20 nia Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an Open Sound System compatibility layer, which provides
|
* This is an Open Sound System compatibility layer, which provides
|
||||||
@ -67,6 +67,7 @@ __RCSID("$NetBSD: ossaudio.c,v 1.55 2020/10/22 19:39:48 nia Exp $");
|
|||||||
|
|
||||||
static struct audiodevinfo *getdevinfo(int);
|
static struct audiodevinfo *getdevinfo(int);
|
||||||
|
|
||||||
|
static int getaudiocount(void);
|
||||||
static int getmixercount(void);
|
static int getmixercount(void);
|
||||||
static int getmixercontrolcount(int);
|
static int getmixercontrolcount(int);
|
||||||
|
|
||||||
@ -1016,6 +1017,7 @@ static int
|
|||||||
mixer_oss4_ioctl(int fd, unsigned long com, void *argp)
|
mixer_oss4_ioctl(int fd, unsigned long com, void *argp)
|
||||||
{
|
{
|
||||||
oss_audioinfo *tmpai;
|
oss_audioinfo *tmpai;
|
||||||
|
oss_card_info *cardinfo;
|
||||||
oss_mixext *ext;
|
oss_mixext *ext;
|
||||||
oss_mixext_root root;
|
oss_mixext_root root;
|
||||||
oss_mixer_enuminfo *ei;
|
oss_mixer_enuminfo *ei;
|
||||||
@ -1147,6 +1149,43 @@ mixer_oss4_ioctl(int fd, unsigned long com, void *argp)
|
|||||||
argp = tmpai;
|
argp = tmpai;
|
||||||
close(newfd);
|
close(newfd);
|
||||||
break;
|
break;
|
||||||
|
case SNDCTL_CARDINFO:
|
||||||
|
cardinfo = (oss_card_info *)argp;
|
||||||
|
if (cardinfo == NULL)
|
||||||
|
return EINVAL;
|
||||||
|
if (cardinfo->card != -1) {
|
||||||
|
snprintf(devname, sizeof(devname),
|
||||||
|
"/dev/audio%d", cardinfo->card);
|
||||||
|
newfd = open(devname, O_RDONLY);
|
||||||
|
if (newfd < 0)
|
||||||
|
return retval;
|
||||||
|
} else {
|
||||||
|
newfd = fd;
|
||||||
|
}
|
||||||
|
retval = ioctl(newfd, AUDIO_GETDEV, &dev);
|
||||||
|
tmperrno = errno;
|
||||||
|
if (newfd != fd)
|
||||||
|
close(newfd);
|
||||||
|
if (retval < 0) {
|
||||||
|
errno = tmperrno;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
strlcpy(cardinfo->shortname, dev.name,
|
||||||
|
sizeof(cardinfo->shortname));
|
||||||
|
snprintf(cardinfo->longname, sizeof(cardinfo->longname),
|
||||||
|
"%s %s %s", dev.name, dev.version, dev.config);
|
||||||
|
memset(cardinfo->hw_info, 0, sizeof(cardinfo->hw_info));
|
||||||
|
/*
|
||||||
|
* OSSv4 does not document this ioctl, and claims it should
|
||||||
|
* not be used by applications and is provided for "utiltiy
|
||||||
|
* programs included in OSS". We follow the Solaris
|
||||||
|
* implementation (which is doucmented) and leave these fields
|
||||||
|
* unset.
|
||||||
|
*/
|
||||||
|
cardinfo->flags = 0;
|
||||||
|
cardinfo->intr_count = 0;
|
||||||
|
cardinfo->ack_count = 0;
|
||||||
|
break;
|
||||||
case SNDCTL_SYSINFO:
|
case SNDCTL_SYSINFO:
|
||||||
memset(&sysinfo, 0, sizeof(sysinfo));
|
memset(&sysinfo, 0, sizeof(sysinfo));
|
||||||
strlcpy(sysinfo.product,
|
strlcpy(sysinfo.product,
|
||||||
@ -1156,13 +1195,14 @@ mixer_oss4_ioctl(int fd, unsigned long com, void *argp)
|
|||||||
strlcpy(sysinfo.license,
|
strlcpy(sysinfo.license,
|
||||||
"BSD", sizeof(sysinfo.license));
|
"BSD", sizeof(sysinfo.license));
|
||||||
sysinfo.versionnum = SOUND_VERSION;
|
sysinfo.versionnum = SOUND_VERSION;
|
||||||
sysinfo.numaudios = OSS_MAX_AUDIO_DEVS;
|
sysinfo.numaudios =
|
||||||
|
sysinfo.numcards =
|
||||||
|
getaudiocount();
|
||||||
sysinfo.numaudioengines = 1;
|
sysinfo.numaudioengines = 1;
|
||||||
sysinfo.numsynths = 1;
|
sysinfo.numsynths = 1;
|
||||||
sysinfo.nummidis = -1;
|
sysinfo.nummidis = -1;
|
||||||
sysinfo.numtimers = -1;
|
sysinfo.numtimers = -1;
|
||||||
sysinfo.nummixers = OSS_MAX_AUDIO_DEVS;
|
sysinfo.nummixers = getmixercount();
|
||||||
sysinfo.numcards = 1;
|
|
||||||
*(struct oss_sysinfo *)argp = sysinfo;
|
*(struct oss_sysinfo *)argp = sysinfo;
|
||||||
break;
|
break;
|
||||||
case SNDCTL_MIXERINFO:
|
case SNDCTL_MIXERINFO:
|
||||||
@ -1552,6 +1592,27 @@ global_oss4_ioctl(int fd, unsigned long com, void *argp)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
getaudiocount(void)
|
||||||
|
{
|
||||||
|
char devname[32];
|
||||||
|
int ndevs = 0;
|
||||||
|
int tmpfd;
|
||||||
|
int tmperrno = errno;
|
||||||
|
|
||||||
|
do {
|
||||||
|
snprintf(devname, sizeof(devname),
|
||||||
|
"/dev/audio%d", ndevs);
|
||||||
|
if ((tmpfd = open(devname, O_RDONLY)) != -1 ||
|
||||||
|
(tmpfd = open(devname, O_WRONLY)) != -1) {
|
||||||
|
ndevs++;
|
||||||
|
close(tmpfd);
|
||||||
|
}
|
||||||
|
} while (tmpfd != -1);
|
||||||
|
errno = tmperrno;
|
||||||
|
return ndevs;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
getmixercount(void)
|
getmixercount(void)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: soundcard.h,v 1.30 2020/10/20 08:57:45 nia Exp $ */
|
/* $NetBSD: soundcard.h,v 1.31 2020/10/23 09:05:20 nia Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1997, 2020 The NetBSD Foundation, Inc.
|
* Copyright (c) 1997, 2020 The NetBSD Foundation, Inc.
|
||||||
@ -407,6 +407,17 @@ typedef struct oss_audioinfo {
|
|||||||
int filler[184]; /* For expansion */
|
int filler[184]; /* For expansion */
|
||||||
} oss_audioinfo;
|
} oss_audioinfo;
|
||||||
|
|
||||||
|
typedef struct oss_card_info {
|
||||||
|
int card;
|
||||||
|
char shortname[16];
|
||||||
|
char longname[128];
|
||||||
|
int flags;
|
||||||
|
char hw_info[400];
|
||||||
|
int intr_count;
|
||||||
|
int ack_count;
|
||||||
|
int filler[154];
|
||||||
|
} oss_card_info;
|
||||||
|
|
||||||
#define SNDCTL_SYSINFO _IOR ('X', 1, oss_sysinfo)
|
#define SNDCTL_SYSINFO _IOR ('X', 1, oss_sysinfo)
|
||||||
#define OSS_SYSINFO SNDCTL_SYSINFO /* Old name */
|
#define OSS_SYSINFO SNDCTL_SYSINFO /* Old name */
|
||||||
#define SNDCTL_MIX_NRMIX _IOR ('X',2, int)
|
#define SNDCTL_MIX_NRMIX _IOR ('X',2, int)
|
||||||
@ -417,6 +428,7 @@ typedef struct oss_audioinfo {
|
|||||||
#define SNDCTL_AUDIOINFO _IOWR ('X',7, oss_audioinfo)
|
#define SNDCTL_AUDIOINFO _IOWR ('X',7, oss_audioinfo)
|
||||||
#define SNDCTL_MIX_ENUMINFO _IOWR ('X',8, oss_mixer_enuminfo)
|
#define SNDCTL_MIX_ENUMINFO _IOWR ('X',8, oss_mixer_enuminfo)
|
||||||
#define SNDCTL_MIXERINFO _IOWR ('X',10, oss_mixerinfo)
|
#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_ENGINEINFO _IOWR ('X',12, oss_audioinfo)
|
||||||
#define SNDCTL_AUDIOINFO_EX _IOWR ('X',13, oss_audioinfo)
|
#define SNDCTL_AUDIOINFO_EX _IOWR ('X',13, oss_audioinfo)
|
||||||
#define SNDCTL_MIX_DESCRIPTION _IOWR ('X',14, oss_mixer_enuminfo)
|
#define SNDCTL_MIX_DESCRIPTION _IOWR ('X',14, oss_mixer_enuminfo)
|
||||||
|
Loading…
Reference in New Issue
Block a user