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
This commit is contained in:
Christos Margiolis committed 2026-08-11 23:56:55 +03:00
1 parent eff55e5e09
commit a753ca9c3f
8 files changed
+43 -139

No files matched your search

+18 -48
View File
@@ -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),
+1 -4
View File
@@ -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");
+2 -6
View File
@@ -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,
+2 -8
View File
@@ -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;
+1 -6
View File
@@ -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) {
+15 -47
View File
@@ -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
+4 -5
View File
@@ -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
-15
View File
@@ -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.