xref: /freebsd/share/man/man4/sndstat.4 (revision 4ce1ba6523839b5c88331de22937b1e0483fc40b)
1c96151d3SKa Ho Ng.\"
2c96151d3SKa Ho Ng.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3c96151d3SKa Ho Ng.\"
4c96151d3SKa Ho Ng.\" This software was developed by Ka Ho Ng
5c96151d3SKa Ho Ng.\" under sponsorship from the FreeBSD Foundation.
6c96151d3SKa Ho Ng.\"
7c96151d3SKa Ho Ng.\" Copyright (c) 2020 The FreeBSD Foundation
8c96151d3SKa Ho Ng.\"
9c96151d3SKa Ho Ng.\" Redistribution and use in source and binary forms, with or without
10c96151d3SKa Ho Ng.\" modification, are permitted provided that the following conditions
11c96151d3SKa Ho Ng.\" are met:
12c96151d3SKa Ho Ng.\" 1. Redistributions of source code must retain the above copyright
13c96151d3SKa Ho Ng.\"    notice, this list of conditions and the following disclaimer.
14c96151d3SKa Ho Ng.\" 2. Redistributions in binary form must reproduce the above copyright
15c96151d3SKa Ho Ng.\"    notice, this list of conditions and the following disclaimer in the
16c96151d3SKa Ho Ng.\"    documentation and/or other materials provided with the distribution.
17c96151d3SKa Ho Ng.\"
18c96151d3SKa Ho Ng.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19c96151d3SKa Ho Ng.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20c96151d3SKa Ho Ng.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21c96151d3SKa Ho Ng.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22c96151d3SKa Ho Ng.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23c96151d3SKa Ho Ng.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24c96151d3SKa Ho Ng.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25c96151d3SKa Ho Ng.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26c96151d3SKa Ho Ng.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27c96151d3SKa Ho Ng.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28c96151d3SKa Ho Ng.\" SUCH DAMAGE.
29c96151d3SKa Ho Ng.\"
30c96151d3SKa Ho Ng.\" $FreeBSD$
31c96151d3SKa Ho Ng.\"
32c96151d3SKa Ho Ng.\" Note: The date here should be updated whenever a non-trivial
33c96151d3SKa Ho Ng.\" change is made to the manual page.
34*4ce1ba65SKa Ho Ng.Dd April 15, 2021
35c96151d3SKa Ho Ng.Dt SNDSTAT 4
36c96151d3SKa Ho Ng.Os
37c96151d3SKa Ho Ng.Sh NAME
38c96151d3SKa Ho Ng.Nm sndstat
39c96151d3SKa Ho Ng.Nd "nvlist-based PCM audio device enumeration interface"
40c96151d3SKa Ho Ng.Sh SYNOPSIS
41c96151d3SKa Ho NgTo compile the driver into the kernel,
42c96151d3SKa Ho Ngplace the following lines in the
43c96151d3SKa Ho Ngkernel configuration file:
44c96151d3SKa Ho Ng.Bd -ragged -offset indent
45c96151d3SKa Ho Ng.Cd "device sound"
46c96151d3SKa Ho Ng.Ed
47c96151d3SKa Ho Ng.Sh DESCRIPTION
48c96151d3SKa Ho NgThe ioctl interface provided by
49c96151d3SKa Ho Ng.Pa /dev/sndstat
50c96151d3SKa Ho Ngdevice allows callers to enumeration PCM audio devices available for use.
51c96151d3SKa Ho Ng.Sh IOCTLS
52c96151d3SKa Ho NgFor all ioctls requiring data exchange between the subsystem and callers,
53c96151d3SKa Ho Ngthe following structures are used to describe a serialized nvlist:
54c96151d3SKa Ho Ng.Bd -literal -offset indent
55*4ce1ba65SKa Ho Ngstruct sndstioc_nv_arg {
56c96151d3SKa Ho Ng	size_t nbytes;
57c96151d3SKa Ho Ng	void *buf;
58c96151d3SKa Ho Ng};
59c96151d3SKa Ho Ng.Ed
60c96151d3SKa Ho Ng.Pp
61c96151d3SKa Ho NgHere is an example of an nvlist, with explanations of the common fields:
62c96151d3SKa Ho Ng.Bd -literal -offset indent
63c96151d3SKa Ho Ngdsps (NVLIST ARRAY): 1
64c96151d3SKa Ho Ng    from_user (BOOL): FALSE
65c96151d3SKa Ho Ng    nameunit (STRING): [pcm0]
66c96151d3SKa Ho Ng    devnode (STRING): [dsp0]
67c96151d3SKa Ho Ng    desc (STRING): [Generic (0x8086) (Analog Line-out)]
68c96151d3SKa Ho Ng    pchan (NUMBER): 1 (1) (0x1)
69c96151d3SKa Ho Ng    rchan (NUMBER): 0 (0) (0x0)
70*4ce1ba65SKa Ho Ng    info_play (NVLIST):
71*4ce1ba65SKa Ho Ng        min_rate (NUMBER): 48000 (48000) (0xbb80)
72*4ce1ba65SKa Ho Ng        max_rate (NUMBER): 48000 (48000) (0xbb80)
73*4ce1ba65SKa Ho Ng        formats (NUMBER): 16 (16) (0x10)
74*4ce1ba65SKa Ho Ng        min_chn (NUMBER): 2 (2) (0x2)
75*4ce1ba65SKa Ho Ng        max_chn (NUMBER): 2 (2) (0x2)
76c96151d3SKa Ho Ng    provider_info (NVLIST):
77c96151d3SKa Ho Ng        unit (NUMBER): 0 (0) (0x0)
78c96151d3SKa Ho Ng        bitperfect (BOOL): FALSE
79c96151d3SKa Ho Ng        pvchan (NUMBER): 1 (1) (0x1)
80c96151d3SKa Ho Ng        rvchan (NUMBER): 0 (0) (0x0)
81c96151d3SKa Ho Ng    provider (STRING): [sound(4)]
82c96151d3SKa Ho Ng    ,
83c96151d3SKa Ho Ng.Ed
84c96151d3SKa Ho Ng.Bl -tag -width ".Dv provider_info"
85c96151d3SKa Ho Ng.It Dv from_user
86c96151d3SKa Ho NgWhether the PCM audio device node is created by in-kernel audio subsystem or
87c96151d3SKa Ho Nguserspace providers.
88c96151d3SKa Ho Ng.It Dv nameunit
89c96151d3SKa Ho NgThe device identification in the form of subsystem plus a unit number.
90c96151d3SKa Ho Ng.It Dv devnode
91c96151d3SKa Ho NgThe PCM audio device node relative path in devfs.
92c96151d3SKa Ho Ng.It Dv desc
93c96151d3SKa Ho NgThe descripton of the PCM audio device.
94c96151d3SKa Ho Ng.It Dv pchan
95c96151d3SKa Ho NgThe number of playback channels supported by hardware.
96c96151d3SKa Ho NgThis can be 0 if this PCM audio device does not support playback at all.
97c96151d3SKa Ho Ng.It Dv rchan
98c96151d3SKa Ho NgThe number of recording channels supported by hardware.
99c96151d3SKa Ho NgThis can be 0 if this PCM audio device does not support recording at all.
100*4ce1ba65SKa Ho Ng.It Dv info_play
101*4ce1ba65SKa Ho NgSupported configurations in playback direction.
102*4ce1ba65SKa Ho NgThis exists only if this PCM audio device supports playback.
103*4ce1ba65SKa Ho NgThere are a number of name/value pairs inside this field:
104*4ce1ba65SKa Ho Ng.Bl -tag -width ".Dv min_rate"
105*4ce1ba65SKa Ho Ng.It Dv min_rate
106*4ce1ba65SKa Ho NgMinimum supported sampling rate.
107*4ce1ba65SKa Ho Ng.It Dv max_rate
108*4ce1ba65SKa Ho NgMaximum supported sampling rate.
109*4ce1ba65SKa Ho Ng.It Dv formats
110*4ce1ba65SKa Ho NgSupported sample formats.
111*4ce1ba65SKa Ho Ng.It Dv min_chn
112*4ce1ba65SKa Ho NgMinimum supported number of channels in channel layout
113*4ce1ba65SKa Ho Ng.It Dv max_chn
114*4ce1ba65SKa Ho NgMaximum supported number of channels in channel layout
115*4ce1ba65SKa Ho Ng.El
116*4ce1ba65SKa Ho Ng.It Dv info_rec
117*4ce1ba65SKa Ho NgSupported configurations in recording direction.
118*4ce1ba65SKa Ho NgThis exists only if this PCM audio device supports recording.
119*4ce1ba65SKa Ho NgThere are a number of name/value pairs inside this field:
120*4ce1ba65SKa Ho Ng.Bl -tag -width ".Dv min_rate"
121*4ce1ba65SKa Ho Ng.It Dv min_rate
122*4ce1ba65SKa Ho NgMinimum supported sampling rate.
123*4ce1ba65SKa Ho Ng.It Dv max_rate
124*4ce1ba65SKa Ho NgMaximum supported sampling rate.
125*4ce1ba65SKa Ho Ng.It Dv formats
126*4ce1ba65SKa Ho NgSupported sample formats.
127*4ce1ba65SKa Ho Ng.It Dv min_chn
128*4ce1ba65SKa Ho NgMinimum supported number of channels in channel layout
129*4ce1ba65SKa Ho Ng.It Dv max_chn
130*4ce1ba65SKa Ho NgMaximum supported number of channels in channel layout
131*4ce1ba65SKa Ho Ng.El
132c96151d3SKa Ho Ng.It Dv provider_info
133c96151d3SKa Ho NgProvider-specific fields.
134c96151d3SKa Ho NgThis field may not exist if the PCM audio device is not provided by in-kernel
135c96151d3SKa Ho Nginterface.
136c96151d3SKa Ho NgThis field will not exist if the provider field is an empty string.
137c96151d3SKa Ho Ng.It Dv provider
138c96151d3SKa Ho NgA string specifying the provider of the PCm audio device.
139c96151d3SKa Ho Ng.El
140c96151d3SKa Ho Ng.Pp
141*4ce1ba65SKa Ho NgThe following ioctls are provided for use:
142*4ce1ba65SKa Ho Ng.Bl -tag -width ".Dv SNDSTIOC_FLUSH_USER_DEVS"
143*4ce1ba65SKa Ho Ng.It Dv SNDSTIOC_REFRESH_DEVS
144c96151d3SKa Ho NgDrop any previously fetched PCM audio devices list snapshots.
145c96151d3SKa Ho NgThis ioctl takes no arguments.
146*4ce1ba65SKa Ho Ng.It Dv SNDSTIOC_GET_DEVS
147c96151d3SKa Ho NgGenerate and/or return PCM audio devices list snapshots to callers.
148c96151d3SKa Ho NgThis ioctl takes a pointer to
149*4ce1ba65SKa Ho Ng.Fa struct sndstioc_nv_arg
150c96151d3SKa Ho Ngas the first and the only argument.
151c96151d3SKa Ho NgCallers need to provide a sufficiently large buffer to hold a serialized
152c96151d3SKa Ho Ngnvlist.
153c96151d3SKa Ho NgIf there is no existing PCM audio device list snapshot available in the
154c96151d3SKa Ho Nginternal structure of the opened sndstat.
155c96151d3SKa Ho Ng.Fa fd ,
156c96151d3SKa Ho Nga new PCM audio device list snapshot will be automatically generated.
157c96151d3SKa Ho NgCallers have to set
158c96151d3SKa Ho Ng.Fa nbytes
159c96151d3SKa Ho Ngto either 0 or the size of buffer provided.
160c96151d3SKa Ho NgIn case
161c96151d3SKa Ho Ng.Fa nbytes
162c96151d3SKa Ho Ngis 0, the buffer size required to hold a serialized nvlist
163c96151d3SKa Ho Ngstream of current snapshot will be returned in
164c96151d3SKa Ho Ng.Fa nbytes ,
165c96151d3SKa Ho Ngand
166c96151d3SKa Ho Ng.Fa buf
167c96151d3SKa Ho Ngwill be ignored.
168c96151d3SKa Ho NgOtherwise, if the buffer is not sufficiently large,
169c96151d3SKa Ho Ngthe ioctl returns success, and
170c96151d3SKa Ho Ng.Fa nbytes
171c96151d3SKa Ho Ngwill be set to 0.
172c96151d3SKa Ho NgIf the buffer provided is sufficiently large,
173c96151d3SKa Ho Ng.Fa nbytes
174c96151d3SKa Ho Ngwill be set to the size of the serialized nvlist written to the provided buffer.
175c96151d3SKa Ho NgOnce a PCM audio device list snapshot is returned to user-space successfully,
176c96151d3SKa Ho Ngthe snapshot stored in the subsystem's internal structure of the given
177c96151d3SKa Ho Ng.Fa fd
178c96151d3SKa Ho Ngwill be freed.
179*4ce1ba65SKa Ho Ng.It Dv SNDSTIOC_ADD_USER_DEVS
180c96151d3SKa Ho NgAdd a list of PCM audio devices provided by callers to
181c96151d3SKa Ho Ng.Pa /dev/sndstat
182c96151d3SKa Ho Ngdevice.
183c96151d3SKa Ho NgThis ioctl takes a pointer to
184*4ce1ba65SKa Ho Ng.Fa struct sndstioc_nv_arg
185c96151d3SKa Ho Ngas the first and the only argument.
186c96151d3SKa Ho NgCallers have to provide a buffer holding a serialized nvlist.
187c96151d3SKa Ho Ng.Fa nbytes
188c96151d3SKa Ho Ngshould be set to the length in bytes of the serialized nvlist.
189c96151d3SKa Ho Ng.Fa buf
190c96151d3SKa Ho Ngshould be pointed to a buffer storing the serialized nvlist.
191c96151d3SKa Ho NgUserspace-backed PCM audio device nodes should be listed inside the serialized
192c96151d3SKa Ho Ngnvlist.
193*4ce1ba65SKa Ho Ng.It Dv SNDSTIOC_FLUSH_USER_DEVS
194c96151d3SKa Ho NgFlush any PCM audio devices previously added by callers.
195c96151d3SKa Ho NgThis ioctl takes no arguments.
196c96151d3SKa Ho Ng.El
197c96151d3SKa Ho Ng.Sh FILES
198c96151d3SKa Ho Ng.Bl -tag -width ".Pa /dev/sndstat" -compact
199c96151d3SKa Ho Ng.It Pa /dev/sndstat
200c96151d3SKa Ho Ng.El
201c96151d3SKa Ho Ng.Sh EXAMPLES
202c96151d3SKa Ho NgThe following code enumerates all available PCM audio devices:
203c96151d3SKa Ho Ng.Bd -literal -offset indent
204c96151d3SKa Ho Ng#include <sys/types.h>
205c96151d3SKa Ho Ng#include <err.h>
206c96151d3SKa Ho Ng#include <fcntl.h>
207c96151d3SKa Ho Ng#include <stdio.h>
208c96151d3SKa Ho Ng#include <stdlib.h>
209c96151d3SKa Ho Ng#include <sys/nv.h>
210c96151d3SKa Ho Ng#include <sys/sndstat.h>
211c96151d3SKa Ho Ng#include <sysexits.h>
212c96151d3SKa Ho Ng#include <unistd.h>
213c96151d3SKa Ho Ng
214c96151d3SKa Ho Ngint
215c96151d3SKa Ho Ngmain()
216c96151d3SKa Ho Ng{
217c96151d3SKa Ho Ng	int fd;
218*4ce1ba65SKa Ho Ng	struct sndstioc_nv_arg arg;
219c96151d3SKa Ho Ng	const nvlist_t * const *di;
220c96151d3SKa Ho Ng	size_t i, nitems;
221c96151d3SKa Ho Ng	nvlist_t *nvl;
222c96151d3SKa Ho Ng
223c96151d3SKa Ho Ng	/* Open sndstat node in read-only first */
224c96151d3SKa Ho Ng	fd = open("/dev/sndstat", O_RDONLY);
225c96151d3SKa Ho Ng
226*4ce1ba65SKa Ho Ng	if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL))
227*4ce1ba65SKa Ho Ng		err(1, "ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL)");
228c96151d3SKa Ho Ng
229c96151d3SKa Ho Ng	/* Get the size of snapshot, when nbytes = 0 */
230c96151d3SKa Ho Ng	arg.nbytes = 0;
231c96151d3SKa Ho Ng	arg.buf = NULL;
232*4ce1ba65SKa Ho Ng	if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
233*4ce1ba65SKa Ho Ng		err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
234c96151d3SKa Ho Ng
235c96151d3SKa Ho Ng	/* Get snapshot data */
236c96151d3SKa Ho Ng	arg.buf = malloc(arg.nbytes);
237c96151d3SKa Ho Ng	if (arg.buf == NULL)
238c96151d3SKa Ho Ng		err(EX_OSERR, "malloc");
239*4ce1ba65SKa Ho Ng	if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg))
240*4ce1ba65SKa Ho Ng		err(1, "ioctl(fd, SNDSTIOC_GET_DEVS, &arg)");
241c96151d3SKa Ho Ng
242c96151d3SKa Ho Ng	/* Deserialize the nvlist stream */
243c96151d3SKa Ho Ng	nvl = nvlist_unpack(arg.buf, arg.nbytes, 0);
244c96151d3SKa Ho Ng	free(arg.buf);
245c96151d3SKa Ho Ng
246c96151d3SKa Ho Ng	/* Get DSPs array */
247*4ce1ba65SKa Ho Ng	di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems);
248c96151d3SKa Ho Ng	for (i = 0; i < nitems; i++) {
249c96151d3SKa Ho Ng		const char *nameunit, *devnode, *desc;
250c96151d3SKa Ho Ng
251c96151d3SKa Ho Ng		/*
252c96151d3SKa Ho Ng		 * Examine each device nvlist item
253c96151d3SKa Ho Ng		 */
254c96151d3SKa Ho Ng
255*4ce1ba65SKa Ho Ng		nameunit = nvlist_get_string(di[i], SNDST_DSPS_NAMEUNIT);
256*4ce1ba65SKa Ho Ng		devnode = nvlist_get_string(di[i], SNDST_DSPS_DEVNODE);
257*4ce1ba65SKa Ho Ng		desc = nvlist_get_string(di[i], SNDST_DSPS_DESC);
258c96151d3SKa Ho Ng		printf("Name unit: `%s`, Device node: `%s`, Description: `%s`\n",
259c96151d3SKa Ho Ng		    nameunit, devnode, desc);
260c96151d3SKa Ho Ng	}
261c96151d3SKa Ho Ng
262c96151d3SKa Ho Ng	nvlist_destroy(nvl);
263c96151d3SKa Ho Ng	return (0);
264c96151d3SKa Ho Ng}
265c96151d3SKa Ho Ng.Ed
266c96151d3SKa Ho Ng.Sh SEE ALSO
267c96151d3SKa Ho Ng.Xr sound 4 ,
268c96151d3SKa Ho Ng.Xr nv 9
269c96151d3SKa Ho Ng.Sh HISTORY
270c96151d3SKa Ho NgThe nvlist-based ioctls support for
271c96151d3SKa Ho Ng.Nm
272c96151d3SKa Ho Ngdevice first appeared in
273c96151d3SKa Ho Ng.Fx 13.0 .
274c96151d3SKa Ho Ng.Sh AUTHORS
275c96151d3SKa Ho NgThis manual page was written by
276c96151d3SKa Ho Ng.An Ka Ho Ng Aq Mt khng@FreeBSD.org .
277