# 修复 snd_hda_intel 回归问题:PCI 重扫描恢复老笔记本音频
在我的 Emachines E732 笔记本上更新内核后,Intel 5 系列/3400 系列 HDA(芯片 ID 8086:3b56)的音频突然消失。aplay -l 显示“未找到声卡”。lspci 能看到设备在 00:1b.0,inxi -Axxz 确认是 snd_hda_intel 驱动,但 journalctl 满是错误:hdaudio hdaudioC0D0: no AFG or MFG node found,所有节点都报错。
dmesg 揭示真相:初始化时出现 snd_hda_intel 0000:00:1b.0: CORB reset timeout#2, CORBRP = 65535,随后是 no codecs initialized。CORB(命令输出环形缓冲区)是编解码器命令的环形缓冲区,0xFFFF 值表示总线挂起或硬件不可访问——读取未初始化的寄存器。
冷启动时的 BAR:mem 0xd4400000-0xd4403fff 64bit。重新加载模块(modprobe -r/-a snd_hda_intel)会重复错误,新时间戳。
无效的快速修复
常规调整完全没用:
- 用户空间工具:重装 PipeWire/WirePlumber,调整 alsamixer——没有 ALSA 设备,一切白搭。
- 模块选项:在
/etc/modprobe.d/alsa-fix.conf中添加options snd-hda-intel enable=1 power_save=0 power_save_controller=N model=auto。 - GRUB 参数:
pci=nocrs pci=nomsi pcie_aspm=off snd_hda_intel.power_save=0 snd_hda_intel.dma_mask=0。 - 热重载:
modprobe snd_hda_intel msi=0 dsp_driver=1 probe_mask=1。
问题出在早期初始化:LTS 内核或 LiveCD 能工作,是因为模块加载顺序或 BIOS 状态不同。
[ 17.492159] snd_hda_intel 0000:00:1b.0: CORB reset timeout#2, CORBRP = 65535
[ 17.492380] snd_hda_intel 0000:00:1b.0: no codecs initialized
解决方案:通过 sysfs 执行 PCI 热重扫描
关键洞察:冷启动分配了错误的 BAR,但系统暖机后的热重扫描有效。步骤如下:
echo 1 | sudo tee /sys/bus/pci/devices/0000:00:1b.0/removesleep 2echo 1 | sudo tee /sys/bus/pci/rescan
新的 dmesg 输出:
[ 473.969035] pci 0000:00:1b.0: [8086:3b56] ...
[ 473.969102] pci 0000:00:1b.0: BAR 0 [mem 0x00000000-0x00003fff 64bit]
[ 473.969982] pci 0000:00:1b.0: BAR 0 [mem 0x23c000000-0x23c003fff 64bit]: assigned
[ 474.095498] input: HDA Intel MID Mic as /devices/pci0000:00/0000:00:1b.0/sound/card0/input24
[ 474.095675] input: HDA Intel MID Headphone as /devices/pci0000:00/0000:00:1b.0/sound/card0/input25
音频恢复:声卡出现在 /dev/snd,PipeWire 检测到设备。罪魁祸首?BIOS 早期提供无效参数;PCI 初始化完成后重扫描分配正确 BAR。
日常自动化
生产环境 systemd 脚本(开机后执行):
#!/bin/bash
PCI_ID="0000:00:1b.0"
echo 1 > /sys/bus/pci/devices/$PCI_ID/remove
sleep 2
echo 1 > /sys/bus/pci/rescan
# 验证
if aplay -l | grep -q "card 0"; then
systemctl --user restart pipewire pipewire-pulse wireplumber
fi
放入 /etc/systemd/system/pci-audio-rescan.service,设置 After=multi-user.target。
诊断类似回归问题
针对旧 Intel HDA 的 snd_hda_intel:
- 收集日志:
dmesg | grep '00:1b.0',journalctl -b -p err | grep hda。 - 检查 BAR:
lspci -vv -s 00:1b.0 | grep BAR。 - 测试重扫描:使用上述 sysfs 方法。
- 对比内核:LTS vs 主线——PCI 分配或电源管理回归。
- BIOS/UEFI:有更新就试试,不过 2010 时代芯片组很少有效。
内核 6.8+ 后,老硬件深受其害:PCI 枚举和 ASPM 变更。
关键要点
- CORBRP=0xFFFF 表示 HDA 控制器卡住,不是 BIOS/编解码器问题。
- sysfs PCI 重扫描 绕过冷启动超时,重新分配 BAR。
- LTS 内核 成功是因为时机:模块在 BIOS 接管后加载。
- 自动化:systemd 服务确保日常使用可靠。
- 诊断:关注 dmesg 而非用户空间;聚焦 PCI BAR 和 CORB/RIRB。
— Editorial Team
暂无评论。