FreeBSD kernel sound device code
unit.c
Go to the documentation of this file.
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3
*
4
* Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*
28
* $FreeBSD$
29
*/
30
31
#include <sys/param.h>
32
#include <sys/systm.h>
33
34
#ifdef HAVE_KERNEL_OPTION_HEADERS
35
#include "opt_snd.h"
36
#endif
37
38
#include <
dev/sound/unit.h
>
39
40
/*
41
* Unit magic allocator for sound driver.
42
*
43
* 'u' = Unit of attached soundcards
44
* 'd' = Device type
45
* 'c' = Channel number
46
*
47
* eg: dsp0.p1 - u=0, d=p, c=1
48
* dsp1.vp0 - u=1, d=vp, c=0
49
* dsp0.10 - u=0, d=clone, c=allocated clone (see further explanation)
50
*
51
* Maximum unit of soundcards can be tuned through "hw.snd.maxunit", which
52
* is between SND_UNIT_UMIN (16) and SND_UNIT_UMAX (2048). By design,
53
* maximum allowable allocated channel is 256, with exception for clone
54
* devices which doesn't have any notion of channel numbering. The use of
55
* channel numbering in a clone device is simply to provide uniqueness among
56
* allocated clones. This also means that the maximum allowable clonable
57
* device is largely dependant and dynamically tuned depending on
58
* hw.snd.maxunit.
59
*/
60
61
/* Default width */
62
static
int
snd_u_shift
= 9;
/* 0 - 0x1ff : 512 distinct soundcards */
63
static
int
snd_d_shift
= 5;
/* 0 - 0x1f : 32 distinct device types */
64
static
int
snd_c_shift
= 10;
/* 0 - 0x3ff : 1024 distinct channels
65
(256 limit "by design",
66
except for clone devices) */
67
68
static
int
snd_unit_initialized
= 0;
69
70
#ifdef SND_DIAGNOSTIC
71
#define SND_UNIT_ASSERT() do { \
72
if (snd_unit_initialized == 0) \
73
panic("%s(): Uninitialized sound unit!"
, __func__); \
74
} while (0)
75
#else
76
#define SND_UNIT_ASSERT() KASSERT(snd_unit_initialized != 0, \
77
("%s(): Uninitialized sound unit!"
, \
78
__func__))
79
#endif
80
81
#define MKMASK(x) ((1 << snd_##x##_shift) - 1)
82
83
int
84
snd_max_u
(
void
)
85
{
86
SND_UNIT_ASSERT
();
87
88
return
(
MKMASK
(u));
89
}
90
91
int
92
snd_max_d
(
void
)
93
{
94
SND_UNIT_ASSERT
();
95
96
return
(
MKMASK
(d));
97
}
98
99
int
100
snd_max_c
(
void
)
101
{
102
SND_UNIT_ASSERT
();
103
104
return
(
MKMASK
(
c
));
105
}
106
107
int
108
snd_unit2u
(
int
unit)
109
{
110
SND_UNIT_ASSERT
();
111
112
return
((unit >> (
snd_c_shift
+
snd_d_shift
)) &
MKMASK
(u));
113
}
114
115
int
116
snd_unit2d
(
int
unit)
117
{
118
SND_UNIT_ASSERT
();
119
120
return
((unit >>
snd_c_shift
) &
MKMASK
(d));
121
}
122
123
int
124
snd_unit2c
(
int
unit)
125
{
126
SND_UNIT_ASSERT
();
127
128
return
(unit &
MKMASK
(
c
));
129
}
130
131
int
132
snd_u2unit
(
int
u)
133
{
134
SND_UNIT_ASSERT
();
135
136
return
((u &
MKMASK
(u)) << (
snd_c_shift
+
snd_d_shift
));
137
}
138
139
int
140
snd_d2unit
(
int
d)
141
{
142
SND_UNIT_ASSERT
();
143
144
return
((d &
MKMASK
(d)) <<
snd_c_shift
);
145
}
146
147
int
148
snd_c2unit
(
int
c
)
149
{
150
SND_UNIT_ASSERT
();
151
152
return
(
c
&
MKMASK
(
c
));
153
}
154
155
int
156
snd_mkunit
(
int
u,
int
d,
int
c
)
157
{
158
SND_UNIT_ASSERT
();
159
160
return
((
c
&
MKMASK
(
c
)) | ((d &
MKMASK
(d)) <<
snd_c_shift
) |
161
((u &
MKMASK
(u)) << (
snd_c_shift
+
snd_d_shift
)));
162
}
163
164
/*
165
* This *must* be called first before any of the functions above!!!
166
*/
167
void
168
snd_unit_init
(
void
)
169
{
170
int
i;
171
172
if
(
snd_unit_initialized
!= 0)
173
return
;
174
175
snd_unit_initialized
= 1;
176
177
if
(getenv_int(
"hw.snd.maxunit"
, &i) != 0) {
178
if
(i <
SND_UNIT_UMIN
)
179
i =
SND_UNIT_UMIN
;
180
else
if
(i >
SND_UNIT_UMAX
)
181
i =
SND_UNIT_UMAX
;
182
else
183
i = roundup2(i, 2);
184
185
for
(
snd_u_shift
= 0; (i >> (
snd_u_shift
+ 1)) != 0;
186
snd_u_shift
++)
187
;
188
189
/*
190
* Make room for channels/clones allocation unit
191
* to fit within 24bit MAXMINOR limit.
192
*/
193
snd_c_shift
= 24 -
snd_u_shift
-
snd_d_shift
;
194
}
195
196
if
(bootverbose != 0)
197
printf(
"%s() u=0x%08x [%d] d=0x%08x [%d] c=0x%08x [%d]\n"
,
198
__func__,
SND_U_MASK
,
snd_max_u
() + 1,
199
SND_D_MASK
,
snd_max_d
() + 1,
SND_C_MASK
,
snd_max_c
() + 1);
200
}
c
struct pcm_channel * c
Definition:
channel_if.m:106
snd_u2unit
int snd_u2unit(int u)
Definition:
unit.c:132
snd_unit2d
int snd_unit2d(int unit)
Definition:
unit.c:116
snd_max_c
int snd_max_c(void)
Definition:
unit.c:100
snd_mkunit
int snd_mkunit(int u, int d, int c)
Definition:
unit.c:156
MKMASK
#define MKMASK(x)
Definition:
unit.c:81
snd_unit_init
void snd_unit_init(void)
Definition:
unit.c:168
snd_max_d
int snd_max_d(void)
Definition:
unit.c:92
snd_d_shift
static int snd_d_shift
Definition:
unit.c:63
snd_d2unit
int snd_d2unit(int d)
Definition:
unit.c:140
snd_unit2u
int snd_unit2u(int unit)
Definition:
unit.c:108
snd_unit_initialized
static int snd_unit_initialized
Definition:
unit.c:68
snd_max_u
int snd_max_u(void)
Definition:
unit.c:84
snd_c2unit
int snd_c2unit(int c)
Definition:
unit.c:148
snd_u_shift
static int snd_u_shift
Definition:
unit.c:62
SND_UNIT_ASSERT
#define SND_UNIT_ASSERT()
Definition:
unit.c:76
snd_unit2c
int snd_unit2c(int unit)
Definition:
unit.c:124
snd_c_shift
static int snd_c_shift
Definition:
unit.c:64
unit.h
SND_UNIT_UMIN
#define SND_UNIT_UMIN
Definition:
unit.h:34
SND_UNIT_UMAX
#define SND_UNIT_UMAX
Definition:
unit.h:35
SND_U_MASK
#define SND_U_MASK
Definition:
unit.h:50
SND_C_MASK
#define SND_C_MASK
Definition:
unit.h:52
SND_D_MASK
#define SND_D_MASK
Definition:
unit.h:51
dev
sound
unit.c
Generated by
1.9.3