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/dev | |
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/dev')
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); |