diff options
-rw-r--r-- | Kernel/Devices/Audio/AC97.cpp | 17 | ||||
-rw-r--r-- | 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 <AK/Format.h> #include <Kernel/Devices/Audio/AC97.h> #include <Kernel/Devices/DeviceManagement.h> #include <Kernel/Memory/AnonymousVMObject.h> @@ -274,8 +275,12 @@ ErrorOr<void> 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<u8>() & 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 <Kernel/Devices/Audio/Controller.h> #include <Kernel/Devices/CharacterDevice.h> #include <Kernel/Interrupts/IRQHandler.h> +#include <Kernel/Locking/SpinlockProtected.h> 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<bool> m_dma_running { false }; StringView m_name; }; |