sound(4): fixing panic for INVARIANTS kernel

3e7bae0821 turns the BUS_READ_IVAR() failure from a warning into a
KASSERT.  For certain PCI audio devices such like snd_csa(4) and
snd_emu10kx(4), the ac97_create() keeps the device handler generated
by device_add_child(pci_dev, "pcm"), which is not really a PCI device
handler.  This in turn causes the subsequent pci_get_subdevice()
inside ac97_initmixer() triggering a panic.

This patch tries to put a bandaid for the aforementioned pcm device
children such that they can use the correct PCI handler(from parent)
to avoid a KASSERT panic in the INVARIANTS kernel.

Tested with:	snd_csa(4), snd_ich(4), snd_emu10kx(4)
Reviewed by:	imp
MFC after:	1 month
This commit is contained in:
Tai-hwa Liang 2021-04-22 12:45:18 +00:00
parent 4281bfec36
commit 2acbe67787

View File

@ -602,6 +602,7 @@ ac97_initmixer(struct ac97_info *codec)
ac97_patch codec_patch;
const char *cname, *vname;
char desc[80];
device_t pdev;
u_int8_t model, step;
unsigned i, j, k, bit, old;
u_int32_t id;
@ -641,9 +642,14 @@ ac97_initmixer(struct ac97_info *codec)
return ENODEV;
}
pdev = codec->dev;
while (strcmp(device_get_name(device_get_parent(pdev)), "pci") != 0) {
/* find the top-level PCI device handler */
pdev = device_get_parent(pdev);
}
codec->id = id;
codec->subvendor = (u_int32_t)pci_get_subdevice(codec->dev) << 16;
codec->subvendor |= (u_int32_t)pci_get_subvendor(codec->dev) &
codec->subvendor = (u_int32_t)pci_get_subdevice(pdev) << 16;
codec->subvendor |= (u_int32_t)pci_get_subvendor(pdev) &
0x0000ffff;
codec->noext = 0;
codec_patch = NULL;