From 1b25513ed715fd38efc2f3ac1d1ba5172cb27e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Sat, 4 Jun 2022 22:29:40 +0200 Subject: [PATCH] Kernel: Don't VERIFY that the DMA channel is running on AC'97 interrupt Fixes #13771; as discussed it's not really a problem to receive an interrupt while the DMA channel is not running, but we do want to log it. --- Kernel/Devices/Audio/AC97.cpp | 17 +++++++++++++---- Kernel/Devices/Audio/AC97.h | 8 ++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Kernel/Devices/Audio/AC97.cpp b/Kernel/Devices/Audio/AC97.cpp index 7d2ced170e..70326df7e4 100644 --- a/Kernel/Devices/Audio/AC97.cpp +++ b/Kernel/Devices/Audio/AC97.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -274,8 +275,12 @@ ErrorOr AC97::write_single_buffer(UserOrKernelBuffer const& data, size_t o void AC97::AC97Channel::handle_dma_stopped() { dbgln_if(AC97_DEBUG, "AC97 @ {}: channel {}: DMA engine has stopped", m_device.pci_address(), name()); - VERIFY(m_dma_running); - m_dma_running = false; + m_dma_running.with([this](auto& dma_running) { + // NOTE: QEMU might send spurious interrupts while we're not running, so we don't want to panic here. + if (!dma_running) + dbgln("AC97 @ {}: received DMA interrupt while it wasn't running", m_device.pci_address()); + dma_running = false; + }); } void AC97::AC97Channel::reset() @@ -288,7 +293,9 @@ void AC97::AC97Channel::reset() while ((control_register.in() & AudioControlRegisterFlag::ResetRegisters) > 0) IO::delay(50); - m_dma_running = false; + m_dma_running.with([](auto& dma_running) { + dma_running = false; + }); } void AC97::AC97Channel::set_last_valid_index(u32 buffer_address, u8 last_valid_index) @@ -310,7 +317,9 @@ void AC97::AC97Channel::start_dma() control |= AudioControlRegisterFlag::InterruptOnCompletionEnable; control_register.out(control); - m_dma_running = true; + m_dma_running.with([](auto& dma_running) { + dma_running = true; + }); } } diff --git a/Kernel/Devices/Audio/AC97.h b/Kernel/Devices/Audio/AC97.h index 1b14493113..c6c5dc158a 100644 --- a/Kernel/Devices/Audio/AC97.h +++ b/Kernel/Devices/Audio/AC97.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace Kernel { @@ -129,7 +130,10 @@ private: { } - bool dma_running() const { return m_dma_running; } + bool dma_running() const + { + return m_dma_running.with([](auto value) { return value; }); + } void handle_dma_stopped(); StringView name() const { return m_name; } IOAddress reg(Register reg) const { return m_channel_base.offset(reg); } @@ -140,7 +144,7 @@ private: private: IOAddress m_channel_base; AC97& m_device; - bool m_dma_running { false }; + SpinlockProtected m_dma_running { false }; StringView m_name; };