git: a753ca9c3f06 - main - sound: Retire sndcard_func

From: Christos Margiolis <christos_at_FreeBSD.org>
Date: Tue, 11 Aug 2026 20:57:01 UTC
The branch main has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=a753ca9c3f0644611e7dfb453af61896fed6c897

commit a753ca9c3f0644611e7dfb453af61896fed6c897
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2026-07-23 21:54:46 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2026-08-11 20:56:55 +0000

    sound: Retire sndcard_func
    
    sndcard_func is used as an ivar which passes around device info to the
    PCM and MIDI children in snd_csa(4) and snd_emu10kx(4). Simplify this
    and retire the need for sndcard_func, by 1) making an ivar only what
    used to be stored in sndcard_func->varinfo, 2) replacing
    sndcard_func->func with a child comparison, where needed, for instance
    in csa_detach().
    
    sndcard_func is harmless in reality, but there is no reason to have the
    additional complexity. This way we also avoid the structure allocations.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
---
 sys/dev/sound/pci/csa.c          | 66 +++++++++++-----------------------------
 sys/dev/sound/pci/csamidi.c      |  5 +--
 sys/dev/sound/pci/csapcm.c       |  8 ++---
 sys/dev/sound/pci/emu10kx-midi.c | 10 ++----
 sys/dev/sound/pci/emu10kx-pcm.c  |  7 +----
 sys/dev/sound/pci/emu10kx.c      | 62 +++++++++----------------------------
 sys/dev/sound/pci/emu10kx.h      |  9 +++---
 sys/dev/sound/pcm/sound.h        | 15 ---------
 8 files changed, 43 insertions(+), 139 deletions(-)

diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c
index c8d4e169f3af..ef3b0a9d2427 100644
--- a/sys/dev/sound/pci/csa.c
+++ b/sys/dev/sound/pci/csa.c
@@ -220,7 +220,6 @@ csa_attach(device_t dev)
 {
 	sc_p scp;
 	csa_res *resp;
-	struct sndcard_func *func;
 	int error = ENXIO;
 
 	scp = device_get_softc(dev);
@@ -274,18 +273,12 @@ csa_attach(device_t dev)
 	/* Attach the children. */
 
 	/* PCM Audio */
-	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
-	func->varinfo = &scp->binfo;
-	func->func = SCF_PCM;
 	scp->pcm = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
-	device_set_ivars(scp->pcm, func);
+	device_set_ivars(scp->pcm, &scp->binfo);
 
 	/* Midi Interface */
-	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
-	func->varinfo = &scp->binfo;
-	func->func = SCF_MIDI;
 	scp->midi = device_add_child(dev, "midi", DEVICE_UNIT_ANY);
-	device_set_ivars(scp->midi, func);
+	device_set_ivars(scp->midi, &scp->binfo);
 
 	bus_attach_children(dev);
 
@@ -302,12 +295,6 @@ err_io:
 	return (error);
 }
 
-static void
-csa_child_deleted(device_t dev, device_t child)
-{
-	free(device_get_ivars(child), M_DEVBUF);
-}
-
 static int
 csa_detach(device_t dev)
 {
@@ -411,7 +398,6 @@ csa_setup_intr(device_t bus, device_t child,
 {
 	sc_p scp;
 	csa_res *resp;
-	struct sndcard_func *func;
 
 	if (filter != NULL) {
 		printf("ata-csa.c: we cannot use a filter here\n");
@@ -420,28 +406,21 @@ csa_setup_intr(device_t bus, device_t child,
 	scp = device_get_softc(bus);
 	resp = &scp->res;
 
-	/*
-	 * Look at the function code of the child to determine
-	 * the appropriate handler for it.
-	 */
-	func = device_get_ivars(child);
-	if (func == NULL || irq != resp->irq)
+	if (irq != resp->irq)
 		return (EINVAL);
 
-	switch (func->func) {
-	case SCF_PCM:
+	/*
+	 * Look at which child device this is to determine the
+	 * appropriate handler for it.
+	 */
+	if (child == scp->pcm) {
 		scp->pcmintr = intr;
 		scp->pcmintr_arg = arg;
-		break;
-
-	case SCF_MIDI:
+	} else if (child == scp->midi) {
 		scp->midiintr = intr;
 		scp->midiintr_arg = arg;
-		break;
-
-	default:
+	} else
 		return (EINVAL);
-	}
 	*cookiep = scp;
 	if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0)
 		csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM);
@@ -455,33 +434,25 @@ csa_teardown_intr(device_t bus, device_t child,
 {
 	sc_p scp;
 	csa_res *resp;
-	struct sndcard_func *func;
 
 	scp = device_get_softc(bus);
 	resp = &scp->res;
 
-	/*
-	 * Look at the function code of the child to determine
-	 * the appropriate handler for it.
-	 */
-	func = device_get_ivars(child);
-	if (func == NULL || irq != resp->irq || cookie != scp)
+	if (irq != resp->irq || cookie != scp)
 		return (EINVAL);
 
-	switch (func->func) {
-	case SCF_PCM:
+	/*
+	 * Look at which child device this is to determine the
+	 * appropriate handler for it.
+	 */
+	if (child == scp->pcm) {
 		scp->pcmintr = NULL;
 		scp->pcmintr_arg = NULL;
-		break;
-
-	case SCF_MIDI:
+	} else if (child == scp->midi) {
 		scp->midiintr = NULL;
 		scp->midiintr_arg = NULL;
-		break;
-
-	default:
+	} else
 		return (EINVAL);
-	}
 
 	return (0);
 }
@@ -1043,7 +1014,6 @@ static device_method_t csa_methods[] = {
 	DEVMETHOD(device_resume,	csa_resume),
 
 	/* Bus interface */
-	DEVMETHOD(bus_child_deleted,	csa_child_deleted),
 	DEVMETHOD(bus_alloc_resource,	csa_alloc_resource),
 	DEVMETHOD(bus_release_resource,	csa_release_resource),
 	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
diff --git a/sys/dev/sound/pci/csamidi.c b/sys/dev/sound/pci/csamidi.c
index e176ac217a56..485aa0c4a880 100644
--- a/sys/dev/sound/pci/csamidi.c
+++ b/sys/dev/sound/pci/csamidi.c
@@ -182,12 +182,9 @@ csamidi_muninit(struct mpu401 *arg __unused, void *cookie)
 static int
 midicsa_probe(device_t dev)
 {
-	struct sndcard_func *func;
-
 	/* The parent device has already been probed. */
 
-	func = device_get_ivars(dev);
-	if (func == NULL || func->func != SCF_MIDI)
+	if (device_get_ivars(dev) == NULL)
 		return (ENXIO);
 
 	device_set_desc(dev, "CS461x MIDI");
diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c
index 154c2f5a9cab..8fd18a2a4361 100644
--- a/sys/dev/sound/pci/csapcm.c
+++ b/sys/dev/sound/pci/csapcm.c
@@ -756,12 +756,10 @@ static int
 pcmcsa_probe(device_t dev)
 {
 	char *s;
-	struct sndcard_func *func;
 
 	/* The parent device has already been probed. */
 
-	func = device_get_ivars(dev);
-	if (func == NULL || func->func != SCF_PCM)
+	if (device_get_ivars(dev) == NULL)
 		return (ENXIO);
 
 	s = "CS461x PCM Audio";
@@ -777,11 +775,9 @@ pcmcsa_attach(device_t dev)
 	csa_res *resp;
 	char status[SND_STATUSLEN];
 	struct ac97_info *codec;
-	struct sndcard_func *func;
 
 	csa = malloc(sizeof(*csa), M_DEVBUF, M_WAITOK | M_ZERO);
-	func = device_get_ivars(dev);
-	csa->binfo = func->varinfo;
+	csa->binfo = device_get_ivars(dev);
 	/*
 	 * Fake the status of DMA so that the initial value of
 	 * PCTL and CCTL can be stored into csa->pctl and csa->cctl,
diff --git a/sys/dev/sound/pci/emu10kx-midi.c b/sys/dev/sound/pci/emu10kx-midi.c
index 2a98562f8f39..0fed9bf3b530 100644
--- a/sys/dev/sound/pci/emu10kx-midi.c
+++ b/sys/dev/sound/pci/emu10kx-midi.c
@@ -138,11 +138,7 @@ static int
 emu_midi_probe(device_t dev)
 {
 	struct emu_midi_softc *scp;
-	uintptr_t func, is_emu10k1;
-
-	BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
-	if (func != SCF_MIDI)
-		return (ENXIO);
+	uintptr_t is_emu10k1;
 
 	scp = device_get_softc(dev);
 	bzero(scp, sizeof(*scp));
@@ -157,15 +153,13 @@ static int
 emu_midi_attach(device_t dev)
 {
 	struct emu_midi_softc * scp;
-	struct sndcard_func *func;
 	struct emu_midiinfo *midiinfo;
 	uint32_t inte_val, ipr_val;
 
 	scp = device_get_softc(dev);
-	func = device_get_ivars(dev);
 
 	scp->dev = dev;
-	midiinfo = (struct emu_midiinfo *)func->varinfo;
+	midiinfo = (struct emu_midiinfo *)device_get_ivars(dev);
 	scp->port = midiinfo->port;
 	scp->card = midiinfo->card;
 
diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c
index b9c8e4291eeb..7cb371d82d39 100644
--- a/sys/dev/sound/pci/emu10kx-pcm.c
+++ b/sys/dev/sound/pci/emu10kx-pcm.c
@@ -1297,14 +1297,9 @@ emu_pcm_uninit(struct emu_pcm_info *sc __unused)
 static int
 emu_pcm_probe(device_t dev)
 {
-	uintptr_t func, route;
+	uintptr_t route;
 	const char *rt;
 
-	BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_FUNC, &func);
-
-	if (func != SCF_PCM)
-		return (ENXIO);
-
 	rt = "UNKNOWN";
 	BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_ROUTE, &route);
 	switch (route) {
diff --git a/sys/dev/sound/pci/emu10kx.c b/sys/dev/sound/pci/emu10kx.c
index 582006e001c2..d3ca81e2fbf7 100644
--- a/sys/dev/sound/pci/emu10kx.c
+++ b/sys/dev/sound/pci/emu10kx.c
@@ -2934,22 +2934,17 @@ emu_uninit(struct emu_sc_info *sc)
 static int
 emu_read_ivar(device_t bus, device_t dev, int ivar_index, uintptr_t * result)
 {
-	struct sndcard_func *func = device_get_ivars(dev);
+	void *varinfo = device_get_ivars(dev);
 	struct emu_sc_info *sc = device_get_softc(bus);
 
-	if (func==NULL)
+	if (varinfo == NULL)
 		return (ENOMEM);
 	if (sc == NULL)
 		return (ENOMEM);
 
 	switch (ivar_index) {
-	case EMU_VAR_FUNC:
-		*result = func->func;
-		break;
 	case EMU_VAR_ROUTE:
-		if (func->varinfo == NULL)
-			return (ENOMEM);
-		*result = ((struct emu_pcminfo *)func->varinfo)->route;
+		*result = ((struct emu_pcminfo *)varinfo)->route;
 		break;
 	case EMU_VAR_ISEMU10K1:
 		*result = sc->is_emu10k1;
@@ -3004,7 +2999,6 @@ emu_pci_probe(device_t dev)
 static int
 emu_pci_attach(device_t dev)
 {
-	struct sndcard_func *func;
 	struct emu_sc_info *sc;
 	struct emu_pcminfo *pcminfo;
 #if 0
@@ -3211,73 +3205,55 @@ emu_pci_attach(device_t dev)
 		sc->pcm[i] = NULL;
 
 	/* FRONT */
-	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 	pcminfo = malloc(sizeof(struct emu_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO);
 	pcminfo->card = sc;
 	pcminfo->route = RT_FRONT;
 
-	func->func = SCF_PCM;
-	func->varinfo = pcminfo;
 	sc->pcm[RT_FRONT] = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
-	device_set_ivars(sc->pcm[RT_FRONT], func);
+	device_set_ivars(sc->pcm[RT_FRONT], pcminfo);
 
 	if (!(sc->mch_disabled)) {
 		/* REAR */
-		func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 		pcminfo = malloc(sizeof(struct emu_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO);
 		pcminfo->card = sc;
 		pcminfo->route = RT_REAR;
 
-		func->func = SCF_PCM;
-		func->varinfo = pcminfo;
 		sc->pcm[RT_REAR] = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
-		device_set_ivars(sc->pcm[RT_REAR], func);
+		device_set_ivars(sc->pcm[RT_REAR], pcminfo);
 		if (sc->has_51) {
 			/* CENTER */
-			func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 			pcminfo = malloc(sizeof(struct emu_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO);
 			pcminfo->card = sc;
 			pcminfo->route = RT_CENTER;
 
-			func->func = SCF_PCM;
-			func->varinfo = pcminfo;
 			sc->pcm[RT_CENTER] = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
-			device_set_ivars(sc->pcm[RT_CENTER], func);
+			device_set_ivars(sc->pcm[RT_CENTER], pcminfo);
 			/* SUB */
-			func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 			pcminfo = malloc(sizeof(struct emu_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO);
 			pcminfo->card = sc;
 			pcminfo->route = RT_SUB;
 
-			func->func = SCF_PCM;
-			func->varinfo = pcminfo;
 			sc->pcm[RT_SUB] = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
-			device_set_ivars(sc->pcm[RT_SUB], func);
+			device_set_ivars(sc->pcm[RT_SUB], pcminfo);
 		}
 		if (sc->has_71) {
 			/* SIDE */
-			func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 			pcminfo = malloc(sizeof(struct emu_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO);
 			pcminfo->card = sc;
 			pcminfo->route = RT_SIDE;
 
-			func->func = SCF_PCM;
-			func->varinfo = pcminfo;
 			sc->pcm[RT_SIDE] = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
-			device_set_ivars(sc->pcm[RT_SIDE], func);
+			device_set_ivars(sc->pcm[RT_SIDE], pcminfo);
 		}
 	} /* mch_disabled */
 
 	if (sc->mch_rec) {
-		func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 		pcminfo = malloc(sizeof(struct emu_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO);
 		pcminfo->card = sc;
 		pcminfo->route = RT_MCHRECORD;
 
-		func->func = SCF_PCM;
-		func->varinfo = pcminfo;
 		sc->pcm[RT_MCHRECORD] = device_add_child(dev, "pcm", DEVICE_UNIT_ANY);
-		device_set_ivars(sc->pcm[RT_MCHRECORD], func);
+		device_set_ivars(sc->pcm[RT_MCHRECORD], pcminfo);
 	} /*mch_rec */
 
 	for (i = 0; i < 2; i++)
@@ -3287,7 +3263,6 @@ emu_pci_attach(device_t dev)
 #if 0
 	/* Midi Interface 1: Live!, Audigy, Audigy 2 */
 	if ((sc->is_emu10k1) || (sc->is_emu10k2) || (sc->is_ca0102)) {
-		func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 		midiinfo = malloc(sizeof(struct emu_midiinfo), M_DEVBUF, M_WAITOK | M_ZERO);
 		midiinfo->card = sc;
 		if (sc->is_emu10k2 || (sc->is_ca0102)) {
@@ -3298,24 +3273,19 @@ emu_pci_attach(device_t dev)
 			midiinfo->port = MUDATA;
 			midiinfo->portnr = 1;
 		}
-		func->func = SCF_MIDI;
-		func->varinfo = midiinfo;
 		sc->midi[0] = device_add_child(dev, "midi", DEVICE_UNIT_ANY);
-		device_set_ivars(sc->midi[0], func);
+		device_set_ivars(sc->midi[0], midiinfo);
 	}
 	/* Midi Interface 2: Audigy, Audigy 2 (on AudigyDrive) */
 	if (sc->is_emu10k2 || (sc->is_ca0102)) {
-		func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_WAITOK | M_ZERO);
 		midiinfo = malloc(sizeof(struct emu_midiinfo), M_DEVBUF, M_WAITOK | M_ZERO);
 		midiinfo->card = sc;
 
 		midiinfo->port = EMU_A_MUDATA2;
 		midiinfo->portnr = 2;
 
-		func->func = SCF_MIDI;
-		func->varinfo = midiinfo;
 		sc->midi[1] = device_add_child(dev, "midi", DEVICE_UNIT_ANY);
-		device_set_ivars(sc->midi[1], func);
+		device_set_ivars(sc->midi[1], midiinfo);
 	}
 #endif
 	bus_attach_children(dev);
@@ -3341,13 +3311,11 @@ bad:
 static void
 emu_pci_child_deleted(device_t dev, device_t child)
 {
-	struct sndcard_func *func;
+	void *varinfo;
 
-	func = device_get_ivars(child);
-	if (func != NULL) {
-		free(func->varinfo, M_DEVBUF);
-		free(func, M_DEVBUF);
-	}
+	varinfo = device_get_ivars(child);
+	if (varinfo != NULL)
+		free(varinfo, M_DEVBUF);
 }
 
 static int
diff --git a/sys/dev/sound/pci/emu10kx.h b/sys/dev/sound/pci/emu10kx.h
index a32ddbf8aebd..102b1fc1d9e8 100644
--- a/sys/dev/sound/pci/emu10kx.h
+++ b/sys/dev/sound/pci/emu10kx.h
@@ -45,11 +45,10 @@
 #define	EMU_MAX_BUFSZ	EMUPAGESIZE*16
 #define	EMU_MAXPAGES	8192
 
-#define	EMU_VAR_FUNC		0
-#define	EMU_VAR_ROUTE		1
-#define	EMU_VAR_ISEMU10K1 	2
-#define	EMU_VAR_MCH_DISABLED 	3
-#define	EMU_VAR_MCH_REC 	4
+#define	EMU_VAR_ROUTE		0
+#define	EMU_VAR_ISEMU10K1 	1
+#define	EMU_VAR_MCH_DISABLED 	2
+#define	EMU_VAR_MCH_REC 	3
 
 #define EMU_A_IOCFG_DISABLE_ANALOG	0x0040	/* = 'enable' for Audigy2 */
 #define EMU_A_IOCFG_GPOUT2	0x0001
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 53bd5a31f06e..f156b557b251 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -162,21 +162,6 @@ void *pcm_getdevinfo(device_t dev);
 int snd_setup_intr(device_t dev, struct resource *res, int flags,
 		   driver_intr_t hand, void *param, void **cookiep);
 
-/* These are the function codes assigned to the children of sound cards. */
-enum {
-	SCF_PCM,
-	SCF_MIDI,
-};
-
-/*
- * This is the device information struct, used by a bridge device to pass the
- * device function code to the children.
- */
-struct sndcard_func {
-	int func;	/* The function code. */
-	void *varinfo;	/* Bridge-specific information. */
-};
-
 /*
  * this is rather kludgey- we need to duplicate these struct def'ns from sound.c
  * so that the macro versions of pcm_{,un}lock can dereference them.