summaryrefslogtreecommitdiff
path: root/Kernel/Devices/Audio
diff options
context:
space:
mode:
authorkleines Filmröllchen <filmroellchen@serenityos.org>2022-06-04 22:29:40 +0200
committerIdan Horowitz <idan.horowitz@gmail.com>2022-06-15 20:53:10 +0300
commit1b25513ed715fd38efc2f3ac1d1ba5172cb27e66 (patch)
treefdafa963aaf876b1e539faa6dca844a2b0b59446 /Kernel/Devices/Audio
parent2c647da0b5528e3e1f08c9eada0d401fd7fd6204 (diff)
downloadserenity-1b25513ed715fd38efc2f3ac1d1ba5172cb27e66.zip
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.
Diffstat (limited to 'Kernel/Devices/Audio')
-rw-r--r--Kernel/Devices/Audio/AC97.cpp17
-rw-r--r--Kernel/Devices/Audio/AC97.h8
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;
};