Module Name:    src
Committed By:   nia
Date:           Fri Oct 23 09:05:20 UTC 2020

Modified Files:
        src/lib/libossaudio: ossaudio.c soundcard.h

Log Message:
ossaudio(3): Add an implementation of SNDCTL_CARDINFO

Correct some of the counts returned by SNDCTL_SYSINFO so this works.


To generate a diff of this commit:
cvs rdiff -u -r1.55 -r1.56 src/lib/libossaudio/ossaudio.c
cvs rdiff -u -r1.30 -r1.31 src/lib/libossaudio/soundcard.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libossaudio/ossaudio.c
diff -u src/lib/libossaudio/ossaudio.c:1.55 src/lib/libossaudio/ossaudio.c:1.56
--- src/lib/libossaudio/ossaudio.c:1.55	Thu Oct 22 19:39:48 2020
+++ src/lib/libossaudio/ossaudio.c	Fri Oct 23 09:05:20 2020
@@ -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.
@@ -27,7 +27,7 @@
  */
 
 #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
@@ -67,6 +67,7 @@ __RCSID("$NetBSD: ossaudio.c,v 1.55 2020
 
 static struct audiodevinfo *getdevinfo(int);
 
+static int getaudiocount(void);
 static int getmixercount(void);
 static int getmixercontrolcount(int);
 
@@ -1016,6 +1017,7 @@ static int
 mixer_oss4_ioctl(int fd, unsigned long com, void *argp)
 {
 	oss_audioinfo *tmpai;
+	oss_card_info *cardinfo;
 	oss_mixext *ext;
 	oss_mixext_root root;
 	oss_mixer_enuminfo *ei;
@@ -1147,6 +1149,43 @@ mixer_oss4_ioctl(int fd, unsigned long c
 		argp = tmpai;
 		close(newfd);
 		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:
 		memset(&sysinfo, 0, sizeof(sysinfo));
 		strlcpy(sysinfo.product,
@@ -1156,13 +1195,14 @@ mixer_oss4_ioctl(int fd, unsigned long c
 		strlcpy(sysinfo.license,
 		    "BSD", sizeof(sysinfo.license));
 		sysinfo.versionnum = SOUND_VERSION;
-		sysinfo.numaudios = OSS_MAX_AUDIO_DEVS;
+		sysinfo.numaudios = 
+		    sysinfo.numcards =
+			getaudiocount();
 		sysinfo.numaudioengines = 1;
 		sysinfo.numsynths = 1;
 		sysinfo.nummidis = -1;
 		sysinfo.numtimers = -1;
-		sysinfo.nummixers = OSS_MAX_AUDIO_DEVS;
-		sysinfo.numcards = 1;
+		sysinfo.nummixers = getmixercount();
 		*(struct oss_sysinfo *)argp = sysinfo;
 		break;
 	case SNDCTL_MIXERINFO:
@@ -1553,6 +1593,27 @@ global_oss4_ioctl(int fd, unsigned long 
 }
 
 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
 getmixercount(void)
 {
 	char devname[32];

Index: src/lib/libossaudio/soundcard.h
diff -u src/lib/libossaudio/soundcard.h:1.30 src/lib/libossaudio/soundcard.h:1.31
--- src/lib/libossaudio/soundcard.h:1.30	Tue Oct 20 08:57:45 2020
+++ src/lib/libossaudio/soundcard.h	Fri Oct 23 09:05:20 2020
@@ -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.
@@ -407,6 +407,17 @@ typedef struct oss_audioinfo {
 	int filler[184];			/* For expansion */
 } 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 OSS_SYSINFO		SNDCTL_SYSINFO /* Old name */
 #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_MIX_ENUMINFO	_IOWR ('X',8, oss_mixer_enuminfo)
 #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)
 #define SNDCTL_MIX_DESCRIPTION	_IOWR ('X',14, oss_mixer_enuminfo)

Reply via email to