1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 17:38:12 +00:00

Kernel: Decouple Intel HDA interrupt handling from controller

The driver would crash if it was unable to find an output route, and
subsequently the destruction of controller did not invoke
`GenericInterruptHandler::will_be_destroyed()` because on the level of
`AudioController`, that method is unavailable.

By decoupling the interrupt handling from the controller, we get a new
refcounted class that correctly cleans up after itself :^)
This commit is contained in:
Jelle Raaijmakers 2023-07-04 11:18:05 +02:00
parent c9af6c87bf
commit 859ac200b7
5 changed files with 76 additions and 17 deletions

View file

@ -14,9 +14,9 @@
#include <Kernel/Bus/PCI/Device.h>
#include <Kernel/Devices/Audio/Channel.h>
#include <Kernel/Devices/Audio/Controller.h>
#include <Kernel/Devices/Audio/IntelHDA/InterruptHandler.h>
#include <Kernel/Devices/Audio/IntelHDA/OutputPath.h>
#include <Kernel/Devices/Audio/IntelHDA/RingBuffer.h>
#include <Kernel/Interrupts/PCIIRQHandler.h>
#include <Kernel/Library/IOWindow.h>
namespace Kernel::Audio::IntelHDA {
@ -27,8 +27,7 @@ class Codec;
class Controller final
: public AudioController
, public PCI::Device
, public PCIIRQHandler {
, public PCI::Device {
public:
static ErrorOr<bool> probe(PCI::DeviceIdentifier const&);
static ErrorOr<NonnullRefPtr<AudioController>> create(PCI::DeviceIdentifier const&);
@ -37,9 +36,7 @@ public:
// ^PCI::Device
virtual StringView device_name() const override { return "IntelHDA"sv; }
// ^PCIIRQHandler
virtual StringView purpose() const override { return "IntelHDA IRQ Handler"sv; }
ErrorOr<bool> handle_interrupt(Badge<InterruptHandler>);
ErrorOr<u32> send_command(u8 codec_address, u8 node_id, CodecControlVerb verb, u16 payload);
private:
@ -81,9 +78,6 @@ private:
ErrorOr<void> configure_output_route();
ErrorOr<void> reset();
// ^PCIIRQHandler
virtual bool handle_irq(RegisterState const&) override;
// ^AudioController
virtual RefPtr<AudioChannel> audio_channel(u32 index) const override;
virtual ErrorOr<size_t> write(size_t channel_index, UserOrKernelBuffer const& data, size_t length) override;
@ -97,6 +91,7 @@ private:
u8 m_number_of_bidirectional_streams;
OwnPtr<CommandOutboundRingBuffer> m_command_buffer;
OwnPtr<ResponseInboundRingBuffer> m_response_buffer;
RefPtr<InterruptHandler> m_interrupt_handler;
Vector<NonnullRefPtr<Codec>> m_codecs {};
OwnPtr<OutputPath> m_output_path;
RefPtr<AudioChannel> m_audio_channel;