diff options
author | cg <cg@FreeBSD.org> | 2001-08-23 11:30:52 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 2001-08-23 11:30:52 +0000 |
commit | 2cfb90cc8dc9d8f8ae1f12afed63cf0409ed6dd2 (patch) | |
tree | 069cd9e58d47e13e77afc32cbb02b958a6dbc95e /sys | |
parent | 1a36f4817c302232acb54087dddcd1d1f4c6a36f (diff) | |
download | FreeBSD-src-2cfb90cc8dc9d8f8ae1f12afed63cf0409ed6dd2.zip FreeBSD-src-2cfb90cc8dc9d8f8ae1f12afed63cf0409ed6dd2.tar.gz |
many changes:
* add new channels to the end of the list so channels used in order of
addition
* de-globalise definition of struct snddev_info and provide accessor
functions where necessary.
* move the $FreeBSD$ tag in each .c file into a macro and allow the
/dev/sndstat handler to display these when set to maximum verbosity to aid
debugging.
* allow each device to register its own sndstat handler to reduce the amount
of groping sndstat must do in foreign structs.
Diffstat (limited to 'sys')
40 files changed, 738 insertions, 407 deletions
diff --git a/sys/dev/sound/isa/ad1816.c b/sys/dev/sound/isa/ad1816.c index 57e01b7..c15992d 100644 --- a/sys/dev/sound/isa/ad1816.c +++ b/sys/dev/sound/isa/ad1816.c @@ -24,8 +24,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -33,6 +31,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + struct ad1816_info; struct ad1816_chinfo { @@ -661,7 +661,7 @@ static device_method_t ad1816_methods[] = { static driver_t ad1816_driver = { "pcm", ad1816_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_ad1816, isa, ad1816_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/isa/es1888.c b/sys/dev/sound/isa/es1888.c index 8dad2ff..2c9e87b 100644 --- a/sys/dev/sound/isa/es1888.c +++ b/sys/dev/sound/isa/es1888.c @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 1999 Doug Rabson * All rights reserved. * @@ -22,13 +22,13 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include <dev/sound/isa/sb.h> +SND_DECLARE_FILE("$FreeBSD$"); + #ifdef __alpha__ static int es1888_dspready(u_int32_t port) diff --git a/sys/dev/sound/isa/ess.c b/sys/dev/sound/isa/ess.c index 6d619f6..6f89197 100644 --- a/sys/dev/sound/isa/ess.c +++ b/sys/dev/sound/isa/ess.c @@ -27,8 +27,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -38,6 +36,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + #define ESS_BUFFSIZE (4096) #define ABS(x) (((x) < 0)? -(x) : (x)) @@ -920,7 +920,7 @@ static device_method_t ess_methods[] = { static driver_t ess_driver = { "pcm", ess_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_ess, sbc, ess_driver, pcm_devclass, 0, 0); @@ -992,7 +992,7 @@ static device_method_t esscontrol_methods[] = { static driver_t esscontrol_driver = { "esscontrol", esscontrol_methods, - sizeof(struct snddev_info), + 1, }; DRIVER_MODULE(esscontrol, isa, esscontrol_driver, esscontrol_devclass, 0, 0); diff --git a/sys/dev/sound/isa/gusc.c b/sys/dev/sound/isa/gusc.c index 1e94e83..54b2928 100644 --- a/sys/dev/sound/isa/gusc.c +++ b/sys/dev/sound/isa/gusc.c @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 1999 Seigo Tanimura * Copyright (c) 1999 Ville-Pertti Keinonen * All rights reserved. @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <sys/param.h> @@ -47,6 +45,8 @@ #include <alpha/isa/isavar.h> #endif +SND_DECLARE_FILE("$FreeBSD$"); + #define LOGICALID_NOPNP 0 #define LOGICALID_PCM 0x0000561e #define LOGICALID_OPL 0x0300561e diff --git a/sys/dev/sound/isa/mss.c b/sys/dev/sound/isa/mss.c index 182380f..e13e1ea 100644 --- a/sys/dev/sound/isa/mss.c +++ b/sys/dev/sound/isa/mss.c @@ -25,12 +25,12 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* board-specific include files */ #include <dev/sound/isa/mss.h> #include <dev/sound/chip.h> @@ -1851,7 +1851,7 @@ static device_method_t mss_methods[] = { static driver_t mss_driver = { "pcm", mss_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_mss, isa, mss_driver, pcm_devclass, 0, 0); @@ -2118,7 +2118,7 @@ static device_method_t pnpmss_methods[] = { static driver_t pnpmss_driver = { "pcm", pnpmss_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_pnpmss, isa, pnpmss_driver, pcm_devclass, 0, 0); @@ -2202,7 +2202,7 @@ static device_method_t guspcm_methods[] = { static driver_t guspcm_driver = { "pcm", guspcm_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_guspcm, gusc, guspcm_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c index ffef450..cfc2363 100644 --- a/sys/dev/sound/isa/sb16.c +++ b/sys/dev/sound/isa/sb16.c @@ -27,8 +27,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -38,6 +36,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + #define SB16_BUFFSIZE 4096 #define PLAIN_SB16(x) ((((x)->bd_flags) & (BD_F_SB16|BD_F_SB16X)) == BD_F_SB16) @@ -844,7 +844,7 @@ static device_method_t sb16_methods[] = { static driver_t sb16_driver = { "pcm", sb16_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_sb16, sbc, sb16_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c index 2b924e3..b02e5e4 100644 --- a/sys/dev/sound/isa/sb8.c +++ b/sys/dev/sound/isa/sb8.c @@ -27,8 +27,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -38,6 +36,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + #define SB_BUFFSIZE 4096 static u_int32_t sb_fmt[] = { @@ -771,7 +771,7 @@ static device_method_t sb_methods[] = { static driver_t sb_driver = { "pcm", sb_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_sb8, sbc, sb_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/isa/sbc.c b/sys/dev/sound/isa/sbc.c index e4d5dd3..4a6ec9b 100644 --- a/sys/dev/sound/isa/sbc.c +++ b/sys/dev/sound/isa/sbc.c @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 1999 Seigo Tanimura * All rights reserved. * @@ -22,14 +22,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/chip.h> #include <dev/sound/pcm/sound.h> #include <dev/sound/isa/sb.h> +SND_DECLARE_FILE("$FreeBSD$"); + #define IO_MAX 3 #define IRQ_MAX 1 #define DRQ_MAX 2 diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c index 0c59aba..a554479 100644 --- a/sys/dev/sound/pci/als4000.c +++ b/sys/dev/sound/pci/als4000.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* @@ -44,6 +42,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + /* Debugging macro's */ #undef DEB #ifndef DEB @@ -887,7 +887,7 @@ static device_method_t als_methods[] = { static driver_t als_driver = { "pcm", als_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_als, pci, als_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/aureal.c b/sys/dev/sound/pci/aureal.c index e629a72..d79626b 100644 --- a/sys/dev/sound/pci/aureal.c +++ b/sys/dev/sound/pci/aureal.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -33,6 +31,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* PCI IDs of supported chips */ #define AU8820_PCI_ID 0x000112eb @@ -677,7 +677,7 @@ static device_method_t au_methods[] = { static driver_t au_driver = { "pcm", au_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_aureal, pci, au_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c index 585be33..6b6b0e7 100644 --- a/sys/dev/sound/pci/cmi.c +++ b/sys/dev/sound/pci/cmi.c @@ -38,8 +38,6 @@ * rate drifts slightly between recordings (usually 0-3%). No * differences visible in register dumps between times that work and * those that don't. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -53,6 +51,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + /* Supported chip ID's */ #define CMI8338A_PCI_ID 0x010013f6 #define CMI8338B_PCI_ID 0x010113f6 @@ -948,7 +948,7 @@ static device_method_t cmi_methods[] = { static driver_t cmi_driver = { "pcm", cmi_methods, - sizeof(struct snddev_info) + PCM_SOFTC_SIZE }; DRIVER_MODULE(snd_cmipci, pci, cmi_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c index 21a2b86..066ffb0 100644 --- a/sys/dev/sound/pci/cs4281.c +++ b/sys/dev/sound/pci/cs4281.c @@ -23,8 +23,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD$ - * * The order of pokes in the initiation sequence is based on Linux * driver by Thomas Sailer, gw boynton (wesb@crystal.cirrus.com), tom * woller (twoller@crystal.cirrus.com). Shingo Watanabe (nabe@nabechan.org) @@ -39,6 +37,8 @@ #include <dev/sound/pci/cs4281.h> +SND_DECLARE_FILE("$FreeBSD$"); + #define CS4281_BUFFER_SIZE 16384 /* Max fifo size for full duplex is 64 */ @@ -970,7 +970,7 @@ static device_method_t cs4281_methods[] = { static driver_t cs4281_driver = { "pcm", cs4281_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_cs4281, pci, cs4281_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c index 015ae94..4d2e506 100644 --- a/sys/dev/sound/pci/csa.c +++ b/sys/dev/sound/pci/csa.c @@ -26,8 +26,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <sys/param.h> @@ -50,6 +48,8 @@ #include <gnu/dev/sound/pci/csaimg.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* This is the pci device id. */ #define CS4610_PCI_ID 0x60011013 #define CS4614_PCI_ID 0x60031013 diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c index 6302781..d0b30ce 100644 --- a/sys/dev/sound/pci/csapcm.c +++ b/sys/dev/sound/pci/csapcm.c @@ -26,8 +26,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <sys/soundcard.h> @@ -40,6 +38,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* Buffer size on dma transfer. Fixed for CS416x. */ #define CS461x_BUFFSIZE (4 * 1024) @@ -839,7 +839,7 @@ static device_method_t pcmcsa_methods[] = { static driver_t pcmcsa_driver = { "pcm", pcmcsa_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c index cb1f848..726af57 100644 --- a/sys/dev/sound/pci/ds1.c +++ b/sys/dev/sound/pci/ds1.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -35,6 +33,8 @@ #include <dev/sound/pci/ds1.h> #include <dev/sound/pci/ds1-fw.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* -------------------------------------------------------------------- */ #define DS1_CHANS 4 @@ -1068,7 +1068,7 @@ static device_method_t ds1_methods[] = { static driver_t ds1_driver = { "pcm", ds1_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_ds1, pci, ds1_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c index 14e0837..583deac 100644 --- a/sys/dev/sound/pci/emu10k1.c +++ b/sys/dev/sound/pci/emu10k1.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -34,6 +32,8 @@ #include <pci/pcivar.h> #include <sys/queue.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* -------------------------------------------------------------------- */ #define EMU10K1_PCI_ID 0x00021102 @@ -1544,7 +1544,7 @@ static device_method_t emu_methods[] = { static driver_t emu_driver = { "pcm", emu_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_emu10k1, pci, emu_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c index ca2fa0c..18700ad 100644 --- a/sys/dev/sound/pci/es137x.c +++ b/sys/dev/sound/pci/es137x.c @@ -37,8 +37,6 @@ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ /* @@ -61,6 +59,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + static int debug = 0; SYSCTL_INT(_debug, OID_AUTO, es_debug, CTLFLAG_RW, &debug, 0, ""); @@ -950,7 +950,7 @@ static device_method_t es_methods[] = { static driver_t es_driver = { "pcm", es_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_es137x, pci, es_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c index 1651572..485ca4d 100644 --- a/sys/dev/sound/pci/fm801.c +++ b/sys/dev/sound/pci/fm801.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -31,6 +29,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +SND_DECLARE_FILE("$FreeBSD$"); + #define PCI_VENDOR_FORTEMEDIA 0x1319 #define PCI_DEVICE_FORTEMEDIA1 0x08011319 #define PCI_DEVICE_FORTEMEDIA2 0x08021319 /* ??? have no idea what's this... */ @@ -700,7 +700,7 @@ static device_method_t fm801_methods[] = { static driver_t fm801_driver = { "pcm", fm801_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_fm801, pci, fm801_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c index 1031536..a4d8aea 100644 --- a/sys/dev/sound/pci/ich.c +++ b/sys/dev/sound/pci/ich.c @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -34,6 +32,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* -------------------------------------------------------------------- */ #define ICH_TIMEOUT 1000 /* semaphore timeout polling count */ @@ -176,7 +176,7 @@ static void ich_filldtbl(struct sc_chinfo *ch) { u_int32_t base; - int i; + int i, bs, gap; base = vtophys(sndbuf_getbuf(ch->buffer)); ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz; @@ -185,10 +185,22 @@ ich_filldtbl(struct sc_chinfo *ch) ch->blksz = sndbuf_getsize(ch->buffer) / ch->blkcnt; } + bs = sndbuf_getsize(ch->buffer) / ICH_DTBL_LENGTH; + gap = ICH_DTBL_LENGTH / ch->blkcnt; + for (i = 0; i < ICH_DTBL_LENGTH; i++) { + ch->dtbl[i].buffer = base + (i * bs); + ch->dtbl[i].length = bs / 2; + if (i % gap == gap - 1) + ch->dtbl[i].length |= ICH_BDC_IOC; + } +#ifdef DALEK for (i = 0; i < ICH_DTBL_LENGTH; i++) { - ch->dtbl[i].buffer = base + (ch->blksz * (i % ch->blkcnt)); - ch->dtbl[i].length = ICH_BDC_IOC | (ch->blksz / 2); + ch->dtbl[i].buffer = base; + ch->dtbl[i].length = ch->blksz / 2; + if (pos % ch->blksz == 0) + ch->dtbl[i].length |= ICH_BDC_IOC; } +#endif } static int @@ -327,7 +339,7 @@ ichchan_getptr(kobj_t obj, void *data) { struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; - u_int32_t ci, ofs, pos; + u_int32_t bs, ci, ofs, pos; ofs = 0; ci = 1234; @@ -336,9 +348,10 @@ ichchan_getptr(kobj_t obj, void *data) ofs = ich_rd(sc, ch->regbase + ICH_REG_X_PICB, 2) * 2; } - ofs = ch->blksz - ofs; - ci %= ch->blkcnt; - pos = (ch->blksz * ci) + ofs; + bs = sndbuf_getsize(ch->buffer) / ICH_DTBL_LENGTH; + ofs = bs - ofs; + pos = ci * bs; + pos += ofs; return pos; } @@ -380,17 +393,17 @@ ich_intr(void *p) st = ich_rd(sc, ch->regbase + ICH_REG_X_SR, 2); st &= ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI; if (st != 0) { - if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) { + /* clear status bit */ + ich_wr(sc, ch->regbase + ICH_REG_X_SR, st, 2); + if (st & (ICH_X_SR_BCIS/* | ICH_X_SR_LVBCI*/)) { /* block complete - update buffer */ if (ch->run) chn_intr(ch->channel); lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1); - lvi++; + lvi += ICH_DTBL_LENGTH / ch->blkcnt; lvi %= ICH_DTBL_LENGTH; ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1); } - /* clear status bit */ - ich_wr(sc, ch->regbase + ICH_REG_X_SR, st, 2); } } } @@ -606,7 +619,7 @@ static device_method_t ich_methods[] = { static driver_t ich_driver = { "pcm", ich_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_ich, pci, ich_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/maestro.c b/sys/dev/sound/pci/maestro.c index 140d6c9..79db926 100644 --- a/sys/dev/sound/pci/maestro.c +++ b/sys/dev/sound/pci/maestro.c @@ -24,7 +24,6 @@ * SUCH DAMAGE. * * $Id: maestro.c,v 1.12 2000/09/06 03:32:34 taku Exp $ - * $FreeBSD$ */ /* @@ -52,6 +51,8 @@ #include <dev/sound/pci/maestro_reg.h> +SND_DECLARE_FILE("$FreeBSD$"); + #define inline __inline /* @@ -1181,7 +1182,7 @@ static device_method_t agg_methods[] = { static driver_t agg_driver = { "pcm", agg_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_maestro, pci, agg_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c index ae23316..3fd7133 100644 --- a/sys/dev/sound/pci/maestro3.c +++ b/sys/dev/sound/pci/maestro3.c @@ -23,8 +23,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ /* @@ -63,6 +61,8 @@ #include <gnu/dev/sound/pci/maestro3_reg.h> #include <gnu/dev/sound/pci/maestro3_dsp.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* -------------------------------------------------------------------- */ enum {CHANGE=0, CALL=1, INTR=2, BORING=3, NONE=-1}; @@ -1493,7 +1493,7 @@ static device_method_t m3_methods[] = { static driver_t m3_driver = { "pcm", m3_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_maestro3, pci, m3_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c index 4ba8615..a97aed4 100644 --- a/sys/dev/sound/pci/neomagic.c +++ b/sys/dev/sound/pci/neomagic.c @@ -24,8 +24,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -36,6 +34,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* -------------------------------------------------------------------- */ #define NM_BUFFSIZE 16384 @@ -741,7 +741,7 @@ static device_method_t nm_methods[] = { static driver_t nm_driver = { "pcm", nm_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_neomagic, pci, nm_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c index c3836f1..13f940f 100644 --- a/sys/dev/sound/pci/solo.c +++ b/sys/dev/sound/pci/solo.c @@ -21,8 +21,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -35,6 +33,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + #define ESS_BUFFSIZE (16384) #define ABS(x) (((x) < 0)? -(x) : (x)) @@ -1002,7 +1002,7 @@ static device_method_t ess_methods[] = { static driver_t ess_driver = { "pcm", ess_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_solo, pci, ess_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c index d298ef1..eb21965b 100644 --- a/sys/dev/sound/pci/t4dwave.c +++ b/sys/dev/sound/pci/t4dwave.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -33,6 +31,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +SND_DECLARE_FILE("$FreeBSD$"); + /* -------------------------------------------------------------------- */ #define TDX_PCI_ID 0x20001023 @@ -825,7 +825,7 @@ static device_method_t tr_methods[] = { static driver_t tr_driver = { "pcm", tr_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(snd_t4dwave, pci, tr_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c index fafaebd..bfc2bf5 100644 --- a/sys/dev/sound/pci/via82c686.c +++ b/sys/dev/sound/pci/via82c686.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -35,6 +33,8 @@ #include <dev/sound/pci/via82c686.h> +SND_DECLARE_FILE("$FreeBSD$"); + #define VIA_PCI_ID 0x30581106 #define NSEGS 4 /* Number of segments in SGD table */ @@ -577,7 +577,7 @@ static device_method_t via_methods[] = { static driver_t via_driver = { "pcm", via_methods, - sizeof(struct snddev_info), + PCM_SOFTC_SIZE, }; DRIVER_MODULE(via, pci, via_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c index add787f..28436b8 100644 --- a/sys/dev/sound/pci/vibes.c +++ b/sys/dev/sound/pci/vibes.c @@ -26,8 +26,7 @@ * This card has the annoying habit of "clicking" when attached and * detached, haven't been able to remedy this with any combination of * muting. - * - * $FreeBSD$ */ + */ #include <dev/sound/pcm/sound.h> #include <dev/sound/pci/vibes.h> @@ -37,6 +36,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + /* ------------------------------------------------------------------------- */ /* Constants */ @@ -919,7 +920,7 @@ static device_method_t sc_methods[] = { static driver_t sonicvibes_driver = { "pcm", sc_methods, - sizeof(struct snddev_info) + PCM_SOFTC_SIZE }; DRIVER_MODULE(snd_sonicvibes, pci, sonicvibes_driver, pcm_devclass, 0, 0); diff --git a/sys/dev/sound/pcm/ac97.c b/sys/dev/sound/pcm/ac97.c index 5e07fe2..bb29063 100644 --- a/sys/dev/sound/pcm/ac97.c +++ b/sys/dev/sound/pcm/ac97.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> @@ -31,6 +29,8 @@ #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + MALLOC_DEFINE(M_AC97, "ac97", "ac97 codec"); struct ac97mixtable_entry { diff --git a/sys/dev/sound/pcm/buffer.c b/sys/dev/sound/pcm/buffer.c index 3cdbf0a..e40c9fd 100644 --- a/sys/dev/sound/pcm/buffer.c +++ b/sys/dev/sound/pcm/buffer.c @@ -22,14 +22,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include "feeder_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + #define MIN(x, y) (((x) < (y))? (x) : (y)) #define SNDBUF_NAMELEN 48 diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 9d9fa8f..6f4893a 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -23,14 +23,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include "feeder_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + #define MIN_CHUNK_SIZE 256 /* for uiomove etc. */ #define DMA_ALIGN_THRESHOLD 4 #define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1)) @@ -276,7 +276,7 @@ chn_write(struct pcm_channel *c, struct uio *buf) if (count <= 0) { c->flags |= CHN_F_DEAD; - device_printf(c->parentsnddev->dev, "play interrupt timeout, channel dead\n"); + printf("play interrupt timeout, channel dead\n", c->name); } return ret; @@ -396,7 +396,7 @@ chn_read(struct pcm_channel *c, struct uio *buf) if (count <= 0) { c->flags |= CHN_F_DEAD; - device_printf(c->parentsnddev->dev, "record interrupt timeout, channel dead\n"); + printf("%s record interrupt timeout, channel dead\n", c->name); } return ret; diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 94b1274..d1ae32f 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -22,8 +22,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <sys/param.h> @@ -31,6 +29,8 @@ #include <dev/sound/pcm/sound.h> +SND_DECLARE_FILE("$FreeBSD$"); + #define OLDPCM_IOCTL static d_open_t dsp_open; @@ -75,6 +75,34 @@ dsp_get_info(dev_t dev) return d; } +static u_int32_t +dsp_get_flags(dev_t dev) +{ + device_t bdev; + int unit; + + unit = PCMUNIT(dev); + if (unit >= devclass_get_maxunit(pcm_devclass)) + return 0xffffffff; + bdev = devclass_get_device(pcm_devclass, unit); + + return pcm_getflags(bdev); +} + +static void +dsp_set_flags(dev_t dev, u_int32_t flags) +{ + device_t bdev; + int unit; + + unit = PCMUNIT(dev); + if (unit >= devclass_get_maxunit(pcm_devclass)) + return; + bdev = devclass_get_device(pcm_devclass, unit); + + pcm_setflags(bdev, flags); +} + /* * return the channels channels associated with an open device instance. * set the priority if the device is simplex and one direction (only) is @@ -85,37 +113,41 @@ static int getchns(dev_t dev, struct pcm_channel **rdch, struct pcm_channel **wrch, u_int32_t prio) { struct snddev_info *d; + u_int32_t flags; + flags = dsp_get_flags(dev); d = dsp_get_info(dev); - snd_mtxlock(d->lock); - d->inprog++; - KASSERT((d->flags & SD_F_PRIO_SET) != SD_F_PRIO_SET, \ + pcm_lock(d); + pcm_inprog(d, 1); + KASSERT((flags & SD_F_PRIO_SET) != SD_F_PRIO_SET, \ ("getchns: read and write both prioritised")); - if ((d->flags & SD_F_PRIO_SET) == 0 && (prio != (SD_F_PRIO_RD | SD_F_PRIO_WR))) - d->flags |= prio & (SD_F_PRIO_RD | SD_F_PRIO_WR); + if ((flags & SD_F_PRIO_SET) == 0 && (prio != (SD_F_PRIO_RD | SD_F_PRIO_WR))) { + flags |= prio & (SD_F_PRIO_RD | SD_F_PRIO_WR); + dsp_set_flags(dev, flags); + } *rdch = dev->si_drv1; *wrch = dev->si_drv2; - if ((d->flags & SD_F_SIMPLEX) && (d->flags & SD_F_PRIO_SET)) { + if ((flags & SD_F_SIMPLEX) && (flags & SD_F_PRIO_SET)) { if (prio) { - if (*rdch && d->flags & SD_F_PRIO_WR) { + if (*rdch && flags & SD_F_PRIO_WR) { dev->si_drv1 = NULL; - *rdch = d->fakechan; - } else if (*wrch && d->flags & SD_F_PRIO_RD) { + *rdch = pcm_getfakechan(d); + } else if (*wrch && flags & SD_F_PRIO_RD) { dev->si_drv2 = NULL; - *wrch = d->fakechan; + *wrch = pcm_getfakechan(d); } } - d->fakechan->flags |= CHN_F_BUSY; + pcm_getfakechan(d)->flags |= CHN_F_BUSY; } + pcm_unlock(d); - if (*rdch && *rdch != d->fakechan && (prio & SD_F_PRIO_RD)) + if (*rdch && *rdch != pcm_getfakechan(d) && (prio & SD_F_PRIO_RD)) CHN_LOCK(*rdch); - if (*wrch && *wrch != d->fakechan && (prio & SD_F_PRIO_WR)) + if (*wrch && *wrch != pcm_getfakechan(d) && (prio & SD_F_PRIO_WR)) CHN_LOCK(*wrch); - snd_mtxunlock(d->lock); return 0; } @@ -127,13 +159,13 @@ relchns(dev_t dev, struct pcm_channel *rdch, struct pcm_channel *wrch, u_int32_t struct snddev_info *d; d = dsp_get_info(dev); - if (wrch && wrch != d->fakechan && (prio & SD_F_PRIO_WR)) + if (wrch && wrch != pcm_getfakechan(d) && (prio & SD_F_PRIO_WR)) CHN_UNLOCK(wrch); - if (rdch && rdch != d->fakechan && (prio & SD_F_PRIO_RD)) + if (rdch && rdch != pcm_getfakechan(d) && (prio & SD_F_PRIO_RD)) CHN_UNLOCK(rdch); - snd_mtxlock(d->lock); - d->inprog--; - snd_mtxunlock(d->lock); + pcm_lock(d); + pcm_inprog(d, -1); + pcm_unlock(d); } static int @@ -172,10 +204,10 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) } /* lock snddev so nobody else can monkey with it */ - snd_mtxlock(d->lock); - if ((d->flags & SD_F_SIMPLEX) && (i_dev->si_drv1 || i_dev->si_drv2)) { + pcm_lock(d); + if ((dsp_get_flags(i_dev) & SD_F_SIMPLEX) && (i_dev->si_drv1 || i_dev->si_drv2)) { /* simplex device, already open, exit */ - snd_mtxunlock(d->lock); + pcm_unlock(d); splx(s); return EBUSY; } @@ -191,14 +223,14 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) rdch = pcm_chnalloc(d, PCMDIR_REC, p->p_pid); if (!rdch) { /* no channel available, exit */ - snd_mtxunlock(d->lock); + pcm_unlock(d); splx(s); return EBUSY; } /* got a channel, already locked for us */ } else { /* already open for read, exit */ - snd_mtxunlock(d->lock); + pcm_unlock(d); splx(s); return EBUSY; } @@ -216,7 +248,7 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) pcm_chnrelease(rdch); } /* exit */ - snd_mtxunlock(d->lock); + pcm_unlock(d); splx(s); return EBUSY; } @@ -228,7 +260,7 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) pcm_chnrelease(rdch); } /* exit */ - snd_mtxunlock(d->lock); + pcm_unlock(d); splx(s); return EBUSY; } @@ -236,7 +268,7 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) i_dev->si_drv1 = rdch; i_dev->si_drv2 = wrch; - snd_mtxunlock(d->lock); + pcm_unlock(d); /* finished with snddev, new channels still locked */ /* bump refcounts, reset and unlock any channels that we just opened */ @@ -276,7 +308,7 @@ dsp_close(dev_t i_dev, int flags, int mode, struct proc *p) s = spltty(); d = dsp_get_info(i_dev); - snd_mtxlock(d->lock); + pcm_lock(d); rdch = i_dev->si_drv1; wrch = i_dev->si_drv2; @@ -298,21 +330,21 @@ dsp_close(dev_t i_dev, int flags, int mode, struct proc *p) } } if (exit) { - snd_mtxunlock(d->lock); + pcm_unlock(d); splx(s); return 0; } /* both refcounts are zero, abort and release */ - if (d->fakechan) - d->fakechan->flags = 0; + if (pcm_getfakechan(d)) + pcm_getfakechan(d)->flags = 0; i_dev->si_drv1 = NULL; i_dev->si_drv2 = NULL; - d->flags &= ~SD_F_TRANSIENT; - snd_mtxunlock(d->lock); + dsp_set_flags(i_dev, dsp_get_flags(i_dev) & ~SD_F_TRANSIENT); + pcm_unlock(d); if (rdch) { chn_abort(rdch); /* won't sleep */ @@ -425,10 +457,6 @@ dsp_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc *p) if (kill & 2) rdch = NULL; - /* - * all routines are called with int. blocked. Make sure that - * ints are re-enabled when calling slow or blocking functions! - */ switch(cmd) { #ifdef OLDPCM_IOCTL /* @@ -527,8 +555,8 @@ dsp_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc *p) p->formats = (rdch? chn_getformats(rdch) : 0xffffffff) & (wrch? chn_getformats(wrch) : 0xffffffff); if (rdch && wrch) - p->formats |= (d->flags & SD_F_SIMPLEX)? 0 : AFMT_FULLDUPLEX; - pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(device_get_unit(d->dev), SND_DEV_CTL, 0)); + p->formats |= (dsp_get_flags(i_dev) & SD_F_SIMPLEX)? 0 : AFMT_FULLDUPLEX; + pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(PCMUNIT(i_dev), SND_DEV_CTL, 0)); p->mixers = 1; /* default: one mixer */ p->inputs = pdev->si_drv1? mix_getdevs(pdev->si_drv1) : 0; p->left = p->right = 100; @@ -842,7 +870,7 @@ dsp_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc *p) case SNDCTL_DSP_GETCAPS: *arg_i = DSP_CAP_REALTIME | DSP_CAP_MMAP | DSP_CAP_TRIGGER; - if (rdch && wrch && !(d->flags & SD_F_SIMPLEX)) + if (rdch && wrch && !(dsp_get_flags(i_dev) & SD_F_SIMPLEX)) *arg_i |= DSP_CAP_DUPLEX; break; diff --git a/sys/dev/sound/pcm/fake.c b/sys/dev/sound/pcm/fake.c index aeb47ef..8c4ba77 100644 --- a/sys/dev/sound/pcm/fake.c +++ b/sys/dev/sound/pcm/fake.c @@ -22,12 +22,12 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> +SND_DECLARE_FILE("$FreeBSD$"); + static u_int32_t fk_fmt[] = { AFMT_U8, AFMT_STEREO | AFMT_U8, diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c index fabf239..102bab2 100644 --- a/sys/dev/sound/pcm/feeder.c +++ b/sys/dev/sound/pcm/feeder.c @@ -22,14 +22,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include "feeder_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + MALLOC_DEFINE(M_FEEDER, "feeder", "pcm feeder"); #define MAXFEEDERS 256 diff --git a/sys/dev/sound/pcm/feeder_fmt.c b/sys/dev/sound/pcm/feeder_fmt.c index 735a5ac..6c8c92a 100644 --- a/sys/dev/sound/pcm/feeder_fmt.c +++ b/sys/dev/sound/pcm/feeder_fmt.c @@ -22,14 +22,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include "feeder_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + MALLOC_DEFINE(M_FMTFEEDER, "fmtfeed", "pcm format feeder"); #define FEEDBUFSZ 8192 diff --git a/sys/dev/sound/pcm/feeder_rate.c b/sys/dev/sound/pcm/feeder_rate.c index 264f643..0cd8a6b 100644 --- a/sys/dev/sound/pcm/feeder_rate.c +++ b/sys/dev/sound/pcm/feeder_rate.c @@ -22,14 +22,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include "feeder_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + MALLOC_DEFINE(M_RATEFEEDER, "ratefeed", "pcm rate feeder"); #define FEEDBUFSZ 8192 diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c index 1fe610f..ba8a473 100644 --- a/sys/dev/sound/pcm/mixer.c +++ b/sys/dev/sound/pcm/mixer.c @@ -22,14 +22,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include "mixer_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + MALLOC_DEFINE(M_MIXER, "mixer", "mixer"); #define MIXER_NAMELEN 16 @@ -320,11 +320,9 @@ sysctl_hw_snd_hwvol_mixer(SYSCTL_HANDLER_ARGS) int mixer_hwvol_init(device_t dev) { - struct snddev_info *d; struct snd_mixer *m; dev_t pdev; - d = device_get_softc(dev); pdev = mixer_get_devt(dev); m = pdev->si_drv1; snd_mtxlock(m->lock); @@ -332,9 +330,9 @@ mixer_hwvol_init(device_t dev) m->hwvol_mixer = SOUND_MIXER_VOLUME; m->hwvol_step = 5; #ifdef SND_DYNSYSCTL - SYSCTL_ADD_INT(&d->sysctl_tree, SYSCTL_CHILDREN(d->sysctl_tree_top), + SYSCTL_ADD_INT(snd_sysctl_tree(dev), SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), OID_AUTO, "hwvol_step", CTLFLAG_RW, &m->hwvol_step, 0, ""); - SYSCTL_ADD_PROC(&d->sysctl_tree, SYSCTL_CHILDREN(d->sysctl_tree_top), + SYSCTL_ADD_PROC(snd_sysctl_tree(dev), SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), OID_AUTO, "hwvol_mixer", CTLTYPE_STRING | CTLFLAG_RW, m, 0, sysctl_hw_snd_hwvol_mixer, "A", "") #endif diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c index 6792700..dd786e9 100644 --- a/sys/dev/sound/pcm/sndstat.c +++ b/sys/dev/sound/pcm/sndstat.c @@ -22,15 +22,19 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include <dev/sound/pcm/vchan.h> -#include <sys/sbuf.h> -#include "feeder_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + +#define SS_TYPE_MODULE 0 +#define SS_TYPE_FIRST 1 +#define SS_TYPE_PCM 1 +#define SS_TYPE_MIDI 2 +#define SS_TYPE_SEQUENCER 3 +#define SS_TYPE_LAST 3 static d_open_t sndstat_open; static d_close_t sndstat_close; @@ -52,16 +56,31 @@ static struct cdevsw sndstat_cdevsw = { /* flags */ 0, }; +struct sndstat_entry { + SLIST_ENTRY(sndstat_entry) link; + device_t dev; + char *str; + sndstat_handler handler; + int type, unit; +}; + +#ifdef USING_MUTEX +static struct mtx sndstat_lock; +#endif static struct sbuf sndstat_sbuf; static dev_t sndstat_dev = 0; static int sndstat_isopen = 0; static int sndstat_bufptr; +static int sndstat_maxunit = -1; +static int sndstat_files = 0; -static int sndstat_verbose = 0; +static SLIST_HEAD(, sndstat_entry) sndstat_devlist = SLIST_HEAD_INITIALIZER(none); + +static int sndstat_verbose = 1; #ifdef USING_MUTEX TUNABLE_INT("hw.snd.verbose", &sndstat_verbose); #else -TUNABLE_INT_DECL("hw.snd.verbose", 0, sndstat_verbose); +TUNABLE_INT_DECL("hw.snd.verbose", 1, sndstat_verbose); #endif static int sndstat_prepare(struct sbuf *s); @@ -69,15 +88,20 @@ static int sndstat_prepare(struct sbuf *s); static int sysctl_hw_sndverbose(SYSCTL_HANDLER_ARGS) { + intrmask_t s; int error, verbose; verbose = sndstat_verbose; error = sysctl_handle_int(oidp, &verbose, sizeof(verbose), req); if (error == 0 && req->newptr != NULL) { - if (verbose == 0 || verbose == 1) - sndstat_verbose = verbose; - else + s = spltty(); + mtx_lock(&sndstat_lock); + if (verbose < 0 || verbose > 3) error = EINVAL; + else + sndstat_verbose = verbose; + mtx_unlock(&sndstat_lock); + splx(s); } return error; } @@ -91,11 +115,14 @@ sndstat_open(dev_t i_dev, int flags, int mode, struct proc *p) int err; s = spltty(); + mtx_lock(&sndstat_lock); if (sndstat_isopen) { + mtx_unlock(&sndstat_lock); splx(s); return EBUSY; } if (sbuf_new(&sndstat_sbuf, NULL, 4096, 0) == NULL) { + mtx_unlock(&sndstat_lock); splx(s); return ENXIO; } @@ -104,6 +131,7 @@ sndstat_open(dev_t i_dev, int flags, int mode, struct proc *p) if (!err) sndstat_isopen = 1; + mtx_unlock(&sndstat_lock); splx(s); return err; } @@ -114,13 +142,16 @@ sndstat_close(dev_t i_dev, int flags, int mode, struct proc *p) intrmask_t s; s = spltty(); + mtx_lock(&sndstat_lock); if (!sndstat_isopen) { + mtx_unlock(&sndstat_lock); splx(s); return EBADF; } sbuf_delete(&sndstat_sbuf); sndstat_isopen = 0; + mtx_unlock(&sndstat_lock); splx(s); return 0; } @@ -132,7 +163,9 @@ sndstat_read(dev_t i_dev, struct uio *buf, int flag) int l, err; s = spltty(); + mtx_lock(&sndstat_lock); if (!sndstat_isopen) { + mtx_unlock(&sndstat_lock); splx(s); return EBADF; } @@ -140,85 +173,169 @@ sndstat_read(dev_t i_dev, struct uio *buf, int flag) err = (l > 0)? uiomove(sbuf_data(&sndstat_sbuf) + sndstat_bufptr, l, buf) : 0; sndstat_bufptr += l; + mtx_unlock(&sndstat_lock); splx(s); return err; } +/************************************************************************/ + +static struct sndstat_entry * +sndstat_find(int type, int unit) +{ + struct sndstat_entry *ent; + + SLIST_FOREACH(ent, &sndstat_devlist, link) { + if (ent->type == type && ent->unit == unit) + return ent; + } + + return NULL; +} + +int +sndstat_register(device_t dev, char *str, sndstat_handler handler) +{ + intrmask_t s; + struct sndstat_entry *ent; + const char *devtype; + int type, unit; + + if (dev) { + unit = device_get_unit(dev); + devtype = device_get_name(dev); + if (!strcmp(devtype, "pcm")) + type = SS_TYPE_PCM; + else if (!strcmp(devtype, "midi")) + type = SS_TYPE_MIDI; + else if (!strcmp(devtype, "sequencer")) + type = SS_TYPE_SEQUENCER; + else + return EINVAL; + } else { + type = SS_TYPE_MODULE; + unit = -1; + } + + ent = malloc(sizeof *ent, M_DEVBUF, M_ZERO | M_WAITOK); + if (!ent) + return ENOSPC; + + ent->dev = dev; + ent->str = str; + ent->type = type; + ent->unit = unit; + ent->handler = handler; + + s = spltty(); + mtx_lock(&sndstat_lock); + SLIST_INSERT_HEAD(&sndstat_devlist, ent, link); + if (type == SS_TYPE_MODULE) + sndstat_files++; + sndstat_maxunit = (unit > sndstat_maxunit)? unit : sndstat_maxunit; + mtx_unlock(&sndstat_lock); + splx(s); + + return 0; +} + +int +sndstat_registerfile(char *str) +{ + return sndstat_register(NULL, str, NULL); +} + +int +sndstat_unregister(device_t dev) +{ + intrmask_t s; + struct sndstat_entry *ent; + + s = spltty(); + mtx_lock(&sndstat_lock); + SLIST_FOREACH(ent, &sndstat_devlist, link) { + if (ent->dev == dev) { + SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link); + free(ent, M_DEVBUF); + mtx_unlock(&sndstat_lock); + splx(s); + + return 0; + } + } + mtx_unlock(&sndstat_lock); + splx(s); + + return ENXIO; +} + +int +sndstat_unregisterfile(char *str) +{ + intrmask_t s; + struct sndstat_entry *ent; + + s = spltty(); + mtx_lock(&sndstat_lock); + SLIST_FOREACH(ent, &sndstat_devlist, link) { + if (ent->dev == NULL && ent->str == str) { + SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link); + free(ent, M_DEVBUF); + sndstat_files--; + mtx_unlock(&sndstat_lock); + splx(s); + + return 0; + } + } + mtx_unlock(&sndstat_lock); + splx(s); + + return ENXIO; +} + +/************************************************************************/ + static int sndstat_prepare(struct sbuf *s) { - int i, pc, rc, vc; - device_t dev; - struct snddev_info *d; - struct snddev_channel *sce; - struct pcm_channel *c; - struct pcm_feeder *f; - - sbuf_printf(s, "FreeBSD Audio Driver (newpcm) %s %s\n", __DATE__, __TIME__); - if (!pcm_devclass || devclass_get_maxunit(pcm_devclass) == 0) { + struct sndstat_entry *ent; + int i, j; + + sbuf_printf(s, "FreeBSD Audio Driver (newpcm)\n"); + if (SLIST_EMPTY(&sndstat_devlist)) { sbuf_printf(s, "No devices installed.\n"); sbuf_finish(s); return sbuf_len(s); - } else - sbuf_printf(s, "Installed devices:\n"); - - for (i = 0; i < devclass_get_maxunit(pcm_devclass); i++) { - d = devclass_get_softc(pcm_devclass, i); - if (!d) - continue; - snd_mtxlock(d->lock); - dev = devclass_get_device(pcm_devclass, i); - sbuf_printf(s, "pcm%d: <%s> %s", i, device_get_desc(dev), d->status); - if (!SLIST_EMPTY(&d->channels)) { - pc = rc = vc = 0; - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - if (c->direction == PCMDIR_PLAY) { - if (c->flags & CHN_F_VIRTUAL) - vc++; - else - pc++; - } else - rc++; - } - sbuf_printf(s, " (%dp/%dr/%dv channels%s%s)\n", pc, rc, vc, - (d->flags & SD_F_SIMPLEX)? "" : " duplex", -#ifdef USING_DEVFS - (i == snd_unit)? " default" : "" -#else - "" -#endif - ); - if (!sndstat_verbose) - goto skipverbose; - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - sbuf_printf(s, "\t%s[%s]: speed %d, format %08x, flags %08x", - c->parentchannel? c->parentchannel->name : "", - c->name, c->speed, c->format, c->flags); - if (c->pid != -1) - sbuf_printf(s, ", pid %d", c->pid); - sbuf_printf(s, "\n\t"); - f = c->feeder; - while (f) { - sbuf_printf(s, "%s", f->class->name); - if (f->desc->type == FEEDER_FMT) - sbuf_printf(s, "(%08x <- %08x)", f->desc->out, f->desc->in); - if (f->desc->type == FEEDER_RATE) - sbuf_printf(s, "(%d <- %d)", FEEDER_GET(f, FEEDRATE_DST), FEEDER_GET(f, FEEDRATE_SRC)); - if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER) - sbuf_printf(s, "(%08x)", f->desc->out); - if (f->source) - sbuf_printf(s, " <- "); - f = f->source; - } - sbuf_printf(s, "\n"); - } -skipverbose: - } else - sbuf_printf(s, " (mixer only)\n"); - snd_mtxunlock(d->lock); + } + + sbuf_printf(s, "Installed devices:\n"); + + for (i = 0; i <= sndstat_maxunit; i++) { + for (j = SS_TYPE_FIRST; j <= SS_TYPE_LAST; j++) { + ent = sndstat_find(j, i); + if (!ent) + continue; + sbuf_printf(s, "%s:", device_get_nameunit(ent->dev)); + sbuf_printf(s, " <%s>", device_get_desc(ent->dev)); + sbuf_printf(s, " %s", ent->str); + if (ent->handler) + ent->handler(s, ent->dev, sndstat_verbose); + else + sbuf_printf(s, " [no handler]"); + sbuf_printf(s, "\n"); + } } + + if (sndstat_verbose >= 3 && sndstat_files > 0) { + sbuf_printf(s, "\nFile Versions:\n"); + + SLIST_FOREACH(ent, &sndstat_devlist, link) { + if (ent->dev == NULL && ent->str != NULL) + sbuf_printf(s, "%s\n", ent->str); + } + } + sbuf_finish(s); return sbuf_len(s); } @@ -226,6 +343,7 @@ skipverbose: static int sndstat_init(void) { + mtx_init(&sndstat_lock, "sndstat", 0); sndstat_dev = make_dev(&sndstat_cdevsw, SND_DEV_STATUS, UID_ROOT, GID_WHEEL, 0444, "sndstat"); return (sndstat_dev != 0)? 0 : ENXIO; @@ -237,7 +355,9 @@ sndstat_uninit(void) intrmask_t s; s = spltty(); + mtx_lock(&sndstat_lock); if (sndstat_isopen) { + mtx_unlock(&sndstat_lock); splx(s); return EBUSY; } @@ -247,6 +367,7 @@ sndstat_uninit(void) sndstat_dev = 0; splx(s); + mtx_destroy(&sndstat_lock); return 0; } @@ -262,7 +383,7 @@ sndstat_sysuninit(void *p) sndstat_uninit(); } -SYSINIT(sndstat_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_sysinit, NULL); -SYSUNINIT(sndstat_sysuninit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_sysuninit, NULL); +SYSINIT(sndstat_sysinit, SI_SUB_DRIVERS, SI_ORDER_FIRST, sndstat_sysinit, NULL); +SYSUNINIT(sndstat_sysuninit, SI_SUB_DRIVERS, SI_ORDER_FIRST, sndstat_sysuninit, NULL); diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index 793b48a..08da0a4 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -23,14 +23,35 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include <dev/sound/pcm/vchan.h> #include <sys/sysctl.h> +#include "feeder_if.h" + +SND_DECLARE_FILE("$FreeBSD$"); + +struct snddev_channel { + SLIST_ENTRY(snddev_channel) link; + struct pcm_channel *channel; +}; + +struct snddev_info { + SLIST_HEAD(, snddev_channel) channels; + struct pcm_channel *fakechan; + unsigned devcount, chancount, vchancount; + unsigned flags; + int inprog; + void *devinfo; + device_t dev; + char status[SND_STATUSLEN]; + struct sysctl_ctx_list sysctl_tree; + struct sysctl_oid *sysctl_tree_top; + void *lock; +}; + devclass_t pcm_devclass; #ifdef USING_DEVFS @@ -38,18 +59,29 @@ int snd_unit = 0; TUNABLE_INT("hw.snd.unit", &snd_unit); #endif -int snd_autovchans = 0; -int snd_maxvchans = 0; -#if __FreeBSD_version > 500000 -TUNABLE_INT("hw.snd.autovchans", &snd_autovchans); -TUNABLE_INT("hw.snd.maxvchans", &snd_maxvchans); -#else -TUNABLE_INT("hw.snd.autovchans", 0, snd_autovchans); -TUNABLE_INT("hw.snd.maxvchans", 0, snd_maxvchans); -#endif +int snd_maxautovchans = 0; +TUNABLE_INT("hw.snd.maxautovchans", &snd_maxautovchans); SYSCTL_NODE(_hw, OID_AUTO, snd, CTLFLAG_RD, 0, "Sound driver"); +static int sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose); + +struct sysctl_ctx_list * +snd_sysctl_tree(device_t dev) +{ + struct snddev_info *d = device_get_softc(dev); + + return &d->sysctl_tree; +} + +struct sysctl_oid * +snd_sysctl_tree_top(device_t dev) +{ + struct snddev_info *d = device_get_softc(dev); + + return d->sysctl_tree_top; +} + void * snd_mtxcreate(const char *desc) { @@ -122,6 +154,24 @@ snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand return bus_setup_intr(dev, res, flags, hand, param, cookiep); } +void +pcm_lock(struct snddev_info *d) +{ + snd_mtxlock(d->lock); +} + +void +pcm_unlock(struct snddev_info *d) +{ + snd_mtxunlock(d->lock); +} + +struct pcm_channel * +pcm_getfakechan(struct snddev_info *d) +{ + return d->fakechan; +} + /* return a locked channel */ struct pcm_channel * pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid) @@ -146,7 +196,7 @@ pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid) /* no channel available */ if (direction == PCMDIR_PLAY) { - if ((d->vchancount > 0) && (d->vchancount < snd_maxvchans)) { + if ((d->vchancount > 0) && (d->vchancount < snd_maxautovchans)) { /* try to create a vchan */ SLIST_FOREACH(sce, &d->channels, link) { c = sce->channel; @@ -186,6 +236,53 @@ pcm_chnref(struct pcm_channel *c, int ref) return r; } +int +pcm_inprog(struct snddev_info *d, int delta) +{ + d->inprog += delta; + return d->inprog; +} + +static void +pcm_setmaxautovchans(struct snddev_info *d, int num) +{ + struct pcm_channel *c; + struct snddev_channel *sce; + int err, done; + + if (num > 0 && d->vchancount == 0) { + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + if ((c->direction == PCMDIR_PLAY) && !(c->flags & CHN_F_BUSY)) { + c->flags |= CHN_F_BUSY; + err = vchan_create(c); + if (err) { + device_printf(d->dev, "vchan_create(%s) == %d\n", c->name, err); + c->flags &= ~CHN_F_BUSY; + } + return; + } + } + } + if (num == 0 && d->vchancount > 0) { + done = 0; + while (!done) { + done = 1; + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + if ((c->flags & CHN_F_VIRTUAL) && !(c->flags & CHN_F_BUSY)) { + done = 0; + err = vchan_destroy(c); + if (err) + device_printf(d->dev, "vchan_destroy(%s) == %d\n", c->name, err); + goto restart; + } + } +restart: + } + } +} + #ifdef USING_DEVFS static int sysctl_hw_snd_unit(SYSCTL_HANDLER_ARGS) @@ -210,38 +307,30 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, unit, CTLTYPE_INT | CTLFLAG_RW, #endif static int -sysctl_hw_snd_autovchans(SYSCTL_HANDLER_ARGS) +sysctl_hw_snd_maxautovchans(SYSCTL_HANDLER_ARGS) { - int v, error; - - v = snd_autovchans; - error = sysctl_handle_int(oidp, &v, sizeof(v), req); - if (error == 0 && req->newptr != NULL) { - if (v < 0 || v >= SND_MAXVCHANS) - return EINVAL; - snd_autovchans = v; - } - return (error); -} -SYSCTL_PROC(_hw_snd, OID_AUTO, autovchans, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(int), sysctl_hw_snd_autovchans, "I", ""); - -static int -sysctl_hw_snd_maxvchans(SYSCTL_HANDLER_ARGS) -{ - int v, error; + struct snddev_info *d; + int i, v, error; - v = snd_maxvchans; + v = snd_maxautovchans; error = sysctl_handle_int(oidp, &v, sizeof(v), req); if (error == 0 && req->newptr != NULL) { if (v < 0 || v >= SND_MAXVCHANS) return EINVAL; - snd_maxvchans = v; + if (v != snd_maxautovchans) { + for (i = 0; i < devclass_get_maxunit(pcm_devclass); i++) { + d = devclass_get_softc(pcm_devclass, i); + if (!d) + continue; + pcm_setmaxautovchans(d, v); + } + } + snd_maxautovchans = v; } return (error); } -SYSCTL_PROC(_hw_snd, OID_AUTO, maxvchans, CTLTYPE_INT | CTLFLAG_RW, - 0, sizeof(int), sysctl_hw_snd_maxvchans, "I", ""); +SYSCTL_PROC(_hw_snd, OID_AUTO, maxautovchans, CTLTYPE_INT | CTLFLAG_RW, + 0, sizeof(int), sysctl_hw_snd_maxautovchans, "I", ""); struct pcm_channel * pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, void *devinfo) @@ -311,7 +400,7 @@ pcm_chn_destroy(struct pcm_channel *ch) int pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev) { - struct snddev_channel *sce; + struct snddev_channel *sce, *tmp, *after; int unit = device_get_unit(d->dev); snd_mtxlock(d->lock); @@ -323,7 +412,15 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev) } sce->channel = ch; - SLIST_INSERT_HEAD(&d->channels, sce, link); + if (SLIST_EMPTY(&d->channels)) { + SLIST_INSERT_HEAD(&d->channels, sce, link); + } else { + after = NULL; + SLIST_FOREACH(tmp, &d->channels, link) { + after = tmp; + } + SLIST_INSERT_AFTER(after, sce, link); + } if (mkdev) dsp_register(unit, d->devcount++); @@ -367,9 +464,8 @@ int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo) { struct snddev_info *d = device_get_softc(dev); - struct pcm_channel *ch, *child; - struct pcmchan_children *pce; - int i, err; + struct pcm_channel *ch; + int err; ch = pcm_chn_create(d, NULL, cls, dir, devinfo); if (!ch) { @@ -384,17 +480,12 @@ pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo) return err; } - if ((dir == PCMDIR_PLAY) && (d->flags & SD_F_AUTOVCHAN) && (snd_autovchans > 0)) { + if (snd_maxautovchans > 0 && (d->flags & SD_F_AUTOVCHAN)) { ch->flags |= CHN_F_BUSY; - for (i = 0; err == 0 && i < snd_autovchans; i++) - err = vchan_create(ch); + err = vchan_create(ch); if (err) { - device_printf(d->dev, "vchan_create(%d) failed, err=%d\n", i - 1, err); - SLIST_FOREACH(pce, &ch->children, link) { - child = pce->channel; - vchan_destroy(child); - } - return err; + device_printf(d->dev, "vchan_create(%s) == %d\n", ch->name, err); + ch->flags &= ~CHN_F_BUSY; } } @@ -449,7 +540,6 @@ pcm_getdevinfo(device_t dev) return d->devinfo; } -/* This is the generic init routine */ int pcm_register(device_t dev, void *devinfo, int numplay, int numrec) { @@ -483,11 +573,12 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec) } #endif if (numplay > 0) - vchan_initsys(d); + vchan_initsys(dev); if (numplay == 1) d->flags |= SD_F_AUTOVCHAN; snd_mtxunlock(d->lock); + sndstat_register(dev, d->status, sndstat_prepare_pcm); return 0; no: snd_mtxfree(d->lock); @@ -533,6 +624,165 @@ pcm_unregister(device_t dev) return 0; } +/************************************************************************/ + +static int +sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) +{ + struct snddev_info *d; + struct snddev_channel *sce; + struct pcm_channel *c; + struct pcm_feeder *f; + int pc, rc, vc; + + if (verbose < 1) + return 0; + + d = device_get_softc(dev); + if (!d) + return ENXIO; + + snd_mtxlock(d->lock); + if (!SLIST_EMPTY(&d->channels)) { + pc = rc = vc = 0; + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + if (c->direction == PCMDIR_PLAY) { + if (c->flags & CHN_F_VIRTUAL) + vc++; + else + pc++; + } else + rc++; + } + sbuf_printf(s, " (%dp/%dr/%dv channels%s%s)", pc, rc, vc, + (d->flags & SD_F_SIMPLEX)? "" : " duplex", +#ifdef USING_DEVFS + (device_get_unit(dev) == snd_unit)? " default" : "" +#else + "" +#endif + ); + if (verbose <= 1) + goto skipverbose; + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + sbuf_printf(s, "\n\t%s[%s]: speed %d, format %08x, flags %08x", + c->parentchannel? c->parentchannel->name : "", + c->name, c->speed, c->format, c->flags); + if (c->pid != -1) + sbuf_printf(s, ", pid %d", c->pid); + sbuf_printf(s, "\n\t"); + f = c->feeder; + while (f) { + sbuf_printf(s, "%s", f->class->name); + if (f->desc->type == FEEDER_FMT) + sbuf_printf(s, "(%08x <- %08x)", f->desc->out, f->desc->in); + if (f->desc->type == FEEDER_RATE) + sbuf_printf(s, "(%d <- %d)", FEEDER_GET(f, FEEDRATE_DST), FEEDER_GET(f, FEEDRATE_SRC)); + if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER) + sbuf_printf(s, "(%08x)", f->desc->out); + if (f->source) + sbuf_printf(s, " <- "); + f = f->source; + } + } +skipverbose: + } else + sbuf_printf(s, " (mixer only)"); + snd_mtxunlock(d->lock); + + return 0; +} + +/************************************************************************/ + +#ifdef SND_DYNSYSCTL +int +sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS) +{ + struct snddev_info *d; + struct snddev_channel *sce; + struct pcm_channel *c; + int err, oldcnt, newcnt, cnt; + + d = oidp->oid_arg1; + + pcm_lock(d); + cnt = 0; + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + if ((c->direction == PCMDIR_PLAY) && (c->flags & CHN_F_VIRTUAL)) + cnt++; + } + oldcnt = cnt; + newcnt = cnt; + + err = sysctl_handle_int(oidp, &newcnt, sizeof(newcnt), req); + if (err == 0 && req->newptr != NULL) { + if (newcnt < 0 || newcnt > SND_MAXVCHANS) { + pcm_unlock(d); + return EINVAL; + } + + if (newcnt > cnt) { + /* add new vchans - find a parent channel first */ + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + /* not a candidate if not a play channel */ + if (c->direction != PCMDIR_PLAY) + goto addskip; + /* not a candidate if a virtual channel */ + if (c->flags & CHN_F_VIRTUAL) + goto addskip; + /* not a candidate if it's in use */ + if ((c->flags & CHN_F_BUSY) && (SLIST_EMPTY(&c->children))) + goto addskip; + /* + * if we get here we're a nonvirtual play channel, and either + * 1) not busy + * 2) busy with children, not directly open + * + * thus we can add children + */ + goto addok; +addskip: + } + pcm_unlock(d); + return EBUSY; +addok: + c->flags |= CHN_F_BUSY; + while (err == 0 && newcnt > cnt) { + err = vchan_create(c); + if (err == 0) + cnt++; + } + if (SLIST_EMPTY(&c->children)) + c->flags &= ~CHN_F_BUSY; + } else if (newcnt < cnt) { + while (err == 0 && newcnt < cnt) { + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + if ((c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL)) == CHN_F_VIRTUAL) + goto remok; + } + pcm_unlock(d); + return EINVAL; +remok: + err = vchan_destroy(c); + if (err == 0) + cnt--; + } + } + } + + pcm_unlock(d); + return err; +} +#endif + +/************************************************************************/ + static moduledata_t sndpcm_mod = { "snd_pcm", NULL, diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h index 3bb0b27..6cc6371 100644 --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -62,6 +62,7 @@ #include <sys/rman.h> #include <sys/mman.h> #include <sys/poll.h> +#include <sys/sbuf.h> #include <sys/soundcard.h> #include <sys/sysctl.h> #include <isa/isavar.h> @@ -76,6 +77,7 @@ #define USING_MUTEX #define USING_DEVFS #endif + #define SND_DYNSYSCTL #ifndef INTR_MPSAFE @@ -86,18 +88,6 @@ #define INTR_MPSAFE 0 #endif -#else -struct isa_device { int dummy; }; -#define d_open_t void -#define d_close_t void -#define d_read_t void -#define d_write_t void -#define d_ioctl_t void -#define d_select_t void -#endif /* _KERNEL */ - -#endif /* _OS_H_ */ - struct pcm_channel; struct pcm_feeder; struct snd_dbuf; @@ -109,27 +99,10 @@ struct snd_mixer; #include <dev/sound/pcm/mixer.h> #include <dev/sound/pcm/dsp.h> -struct snddev_channel { - SLIST_ENTRY(snddev_channel) link; - struct pcm_channel *channel; -}; +#define PCM_SOFTC_SIZE 512 #define SND_STATUSLEN 64 /* descriptor of audio device */ -struct snddev_info { - SLIST_HEAD(, snddev_channel) channels; - struct pcm_channel *fakechan; - unsigned devcount, chancount, vchancount; - unsigned flags; - int inprog; - void *devinfo; - device_t dev; - char status[SND_STATUSLEN]; - struct sysctl_ctx_list sysctl_tree; - struct sysctl_oid *sysctl_tree_top; - void *lock; -}; - #ifndef ISADMA_WRITE #define ISADMA_WRITE B_WRITE #define ISADMA_READ B_READ @@ -224,8 +197,6 @@ int fkchan_kill(struct pcm_channel *c); #define ON 1 #define OFF 0 -#ifdef _KERNEL - extern int snd_unit; extern devclass_t pcm_devclass; @@ -243,9 +214,16 @@ extern devclass_t pcm_devclass; SYSCTL_DECL(_hw_snd); +struct sysctl_ctx_list *snd_sysctl_tree(device_t dev); +struct sysctl_oid *snd_sysctl_tree_top(device_t dev); + +void pcm_lock(struct snddev_info *d); +void pcm_unlock(struct snddev_info *d); +struct pcm_channel *pcm_getfakechan(struct snddev_info *d); struct pcm_channel *pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid); int pcm_chnrelease(struct pcm_channel *c); int pcm_chnref(struct pcm_channel *c, int ref); +int pcm_inprog(struct snddev_info *d, int delta); struct pcm_channel *pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, void *devinfo); int pcm_chn_destroy(struct pcm_channel *ch); @@ -268,7 +246,25 @@ void snd_mtxfree(void *m); void snd_mtxassert(void *m); void snd_mtxlock(void *m); void snd_mtxunlock(void *m); -#endif /* _KERNEL */ + +int sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS); + +typedef int (*sndstat_handler)(struct sbuf *s, device_t dev, int verbose); +int sndstat_register(device_t dev, char *str, sndstat_handler handler); +int sndstat_registerfile(char *str); +int sndstat_unregister(device_t dev); +int sndstat_unregisterfile(char *str); + +#define SND_DECLARE_FILE(version) \ + _SND_DECLARE_FILE(__LINE__, version) + +#define _SND_DECLARE_FILE(uniq, version) \ + __SND_DECLARE_FILE(uniq, version) + +#define __SND_DECLARE_FILE(uniq, version) \ + static char sndstat_vinfo[] = version; \ + SYSINIT(sdf_ ## uniq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_registerfile, sndstat_vinfo); \ + SYSUNINIT(sdf_ ## uniq, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sndstat_unregisterfile, sndstat_vinfo); /* usage of flags in device config entry (config file) */ #define DV_F_DRQ_MASK 0x00000007 /* mask for secondary drq */ @@ -277,3 +273,7 @@ void snd_mtxunlock(void *m); /* ought to be made obsolete */ #define DV_F_DEV_MASK 0x0000ff00 /* force device type/class */ #define DV_F_DEV_SHIFT 8 /* force device type/class */ + +#endif /* _KERNEL */ + +#endif /* _OS_H_ */ diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c index 7a8d41d..46b3061 100644 --- a/sys/dev/sound/pcm/vchan.c +++ b/sys/dev/sound/pcm/vchan.c @@ -22,14 +22,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ #include <dev/sound/pcm/sound.h> #include <dev/sound/pcm/vchan.h> #include "feeder_if.h" +SND_DECLARE_FILE("$FreeBSD$"); + struct vchinfo { u_int32_t spd, fmt, blksz, bps, run; struct pcm_channel *channel, *parent; @@ -42,7 +42,6 @@ static u_int32_t vchan_fmt[] = { 0 }; - static int vchan_mix_s16(int16_t *to, int16_t *tmp, unsigned int count) { @@ -327,98 +326,18 @@ gotch: return err; } -#ifdef SND_DYNSYSCTL -static int -sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS) -{ - struct snddev_info *d; - struct snddev_channel *sce; - struct pcm_channel *c; - int err, oldcnt, newcnt, cnt; - - d = oidp->oid_arg1; - - snd_mtxlock(d->lock); - cnt = 0; - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - if ((c->direction == PCMDIR_PLAY) && (c->flags & CHN_F_VIRTUAL)) - cnt++; - } - oldcnt = cnt; - newcnt = cnt; - - err = sysctl_handle_int(oidp, &newcnt, sizeof(newcnt), req); - if (err == 0 && req->newptr != NULL) { - if (newcnt < 0 || newcnt > SND_MAXVCHANS) { - snd_mtxunlock(d->lock); - return EINVAL; - } - - if (newcnt > cnt) { - /* add new vchans - find a parent channel first */ - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - /* not a candidate if not a play channel */ - if (c->direction != PCMDIR_PLAY) - goto addskip; - /* not a candidate if a virtual channel */ - if (c->flags & CHN_F_VIRTUAL) - goto addskip; - /* not a candidate if it's in use */ - if ((c->flags & CHN_F_BUSY) && (SLIST_EMPTY(&c->children))) - goto addskip; - /* - * if we get here we're a nonvirtual play channel, and either - * 1) not busy - * 2) busy with children, not directly open - * - * thus we can add children - */ - goto addok; -addskip: - } - snd_mtxunlock(d->lock); - return EBUSY; -addok: - c->flags |= CHN_F_BUSY; - while (err == 0 && newcnt > cnt) { - err = vchan_create(c); - if (err == 0) - cnt++; - } - if (SLIST_EMPTY(&c->children)) - c->flags &= ~CHN_F_BUSY; - } else if (newcnt < cnt) { - while (err == 0 && newcnt < cnt) { - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - if ((c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL)) == CHN_F_VIRTUAL) - goto remok; - } - snd_mtxunlock(d->lock); - return EINVAL; -remok: - err = vchan_destroy(c); - if (err == 0) - cnt--; - } - } - } - - snd_mtxunlock(d->lock); - return err; -} -#endif - int -vchan_initsys(struct snddev_info *d) +vchan_initsys(device_t dev) { #ifdef SND_DYNSYSCTL - SYSCTL_ADD_PROC(&d->sysctl_tree, SYSCTL_CHILDREN(d->sysctl_tree_top), + struct snddev_info *d; + + d = device_get_softc(dev); + SYSCTL_ADD_PROC(snd_sysctl_tree(dev), SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), OID_AUTO, "vchans", CTLTYPE_INT | CTLFLAG_RW, d, sizeof(d), sysctl_hw_snd_vchans, "I", "") #endif + return 0; } diff --git a/sys/dev/sound/pcm/vchan.h b/sys/dev/sound/pcm/vchan.h index 7e057ce..d3121e9 100644 --- a/sys/dev/sound/pcm/vchan.h +++ b/sys/dev/sound/pcm/vchan.h @@ -28,6 +28,6 @@ int vchan_create(struct pcm_channel *parent); int vchan_destroy(struct pcm_channel *c); -int vchan_initsys(struct snddev_info *d); +int vchan_initsys(device_t dev); |