Compare commits

..

2 Commits

Author SHA1 Message Date
1fcd72e578 Kernel: replaced is_partition/storage with kind 2026-05-15 21:37:18 +03:00
5e1b5c329b Kernel: Allow HDA stream reset to timeout
This was hanging on some version of qemu :^)
2026-05-15 21:30:41 +03:00
7 changed files with 38 additions and 20 deletions

View File

@@ -43,7 +43,7 @@ namespace Kernel
BAN::ErrorOr<void> enable_output_path(uint8_t index); BAN::ErrorOr<void> enable_output_path(uint8_t index);
BAN::ErrorOr<void> disable_output_path(uint8_t index); BAN::ErrorOr<void> disable_output_path(uint8_t index);
void reset_stream(); BAN::ErrorOr<void> reset_stream();
BAN::ErrorOr<void> recurse_output_paths(const HDAudio::AFGWidget& widget, BAN::Vector<const HDAudio::AFGWidget*>& path); BAN::ErrorOr<void> recurse_output_paths(const HDAudio::AFGWidget& widget, BAN::Vector<const HDAudio::AFGWidget*>& path);

View File

@@ -12,9 +12,6 @@ namespace Kernel
virtual ~Device() = default; virtual ~Device() = default;
virtual void update() {} virtual void update() {}
virtual bool is_partition() const { return false; }
virtual bool is_storage_device() const { return false; }
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t, int status_flags) virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t, int status_flags)
{ {
(void)offset; (void)len; (void)status_flags; (void)offset; (void)len; (void)status_flags;

View File

@@ -62,10 +62,12 @@ namespace Kernel
mode_t mode; mode_t mode;
}; };
enum InodeKind : uint8_t { enum InodeKind : uint8_t {
DEVICE = 0x1, DEVICE = 0x01,
EPOLL = 0x2, EPOLL = 0x02,
PIPE = 0x4, PIPE = 0x04,
TTY = 0x8, TTY = 0x08,
PARTITION = 0x10,
STORAGE = 0x20,
}; };
public: public:
virtual ~Inode() {} virtual ~Inode() {}
@@ -88,10 +90,12 @@ namespace Kernel
dev_t dev() const { return m_dev; } dev_t dev() const { return m_dev; }
dev_t rdev() const { return m_rdev; } dev_t rdev() const { return m_rdev; }
bool is_device() const { return m_kind & InodeKind::DEVICE; } bool is_device() const { return m_kind & InodeKind::DEVICE; }
bool is_epoll() const { return m_kind & InodeKind::EPOLL; } bool is_epoll() const { return m_kind & InodeKind::EPOLL; }
bool is_pipe() const { return m_kind & InodeKind::PIPE; } bool is_pipe() const { return m_kind & InodeKind::PIPE; }
bool is_tty() const { return m_kind & InodeKind::TTY; } bool is_tty() const { return m_kind & InodeKind::TTY; }
bool is_partition() const { return m_kind & InodeKind::PARTITION; }
bool is_storage_device() const { return m_kind & InodeKind::STORAGE; }
virtual const FileSystem* filesystem() const = 0; virtual const FileSystem* filesystem() const = 0;

View File

@@ -42,9 +42,6 @@ namespace Kernel
char m_label[36 * 4 + 1]; char m_label[36 * 4 + 1];
const BAN::String m_name; const BAN::String m_name;
public:
virtual bool is_partition() const override { return true; }
protected: protected:
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override; virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;

View File

@@ -14,7 +14,10 @@ namespace Kernel
public: public:
StorageDevice() StorageDevice()
: BlockDevice(0660, 0, 0) : BlockDevice(0660, 0, 0)
{ } {
m_kind |= InodeKind::STORAGE;
}
virtual ~StorageDevice(); virtual ~StorageDevice();
BAN::ErrorOr<void> initialize_partitions(BAN::StringView name_prefix); BAN::ErrorOr<void> initialize_partitions(BAN::StringView name_prefix);
@@ -35,7 +38,6 @@ namespace Kernel
size_t drop_disk_cache(); size_t drop_disk_cache();
BAN::ErrorOr<void> sync_disk_cache(); BAN::ErrorOr<void> sync_disk_cache();
virtual bool is_storage_device() const override { return true; }
protected: protected:
virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan) = 0; virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan) = 0;

View File

@@ -1,6 +1,7 @@
#include <kernel/Audio/HDAudio/AudioFunctionGroup.h> #include <kernel/Audio/HDAudio/AudioFunctionGroup.h>
#include <kernel/Audio/HDAudio/Registers.h> #include <kernel/Audio/HDAudio/Registers.h>
#include <kernel/FS/DevFS/FileSystem.h> #include <kernel/FS/DevFS/FileSystem.h>
#include <kernel/Timer/Timer.h>
#include <BAN/Sort.h> #include <BAN/Sort.h>
@@ -202,12 +203,12 @@ namespace Kernel
ASSERT(m_stream_index == 0xFF); ASSERT(m_stream_index == 0xFF);
m_stream_index = TRY(m_controller->allocate_stream(HDAudio::StreamType::Output, this)); m_stream_index = TRY(m_controller->allocate_stream(HDAudio::StreamType::Output, this));
reset_stream(); TRY(reset_stream());
return {}; return {};
} }
void HDAudioFunctionGroup::reset_stream() BAN::ErrorOr<void> HDAudioFunctionGroup::reset_stream()
{ {
using Regs = HDAudio::Regs; using Regs = HDAudio::Regs;
@@ -219,13 +220,23 @@ namespace Kernel
// stop stream // stop stream
bar.write8(base + Regs::SDCTL, bar.read8(base + Regs::SDCTL) & 0xFD); bar.write8(base + Regs::SDCTL, bar.read8(base + Regs::SDCTL) & 0xFD);
const auto timeout_ms = SystemTimer::get().ms_since_boot() + 100;
// reset stream // reset stream
bar.write8(base + Regs::SDCTL, (bar.read8(base + Regs::SDCTL) & 0xFE) | 1); bar.write8(base + Regs::SDCTL, (bar.read8(base + Regs::SDCTL) & 0xFE) | 1);
while (!(bar.read8(base + Regs::SDCTL) & 1)) while (!(bar.read8(base + Regs::SDCTL) & 1))
{
if (SystemTimer::get().ms_since_boot() > timeout_ms)
return BAN::Error::from_errno(ETIMEDOUT);
Processor::pause(); Processor::pause();
}
bar.write8(base + Regs::SDCTL, (bar.read8(base + Regs::SDCTL) & 0xFE)); bar.write8(base + Regs::SDCTL, (bar.read8(base + Regs::SDCTL) & 0xFE));
while ((bar.read8(base + Regs::SDCTL) & 1)) while ((bar.read8(base + Regs::SDCTL) & 1))
{
if (SystemTimer::get().ms_since_boot() > timeout_ms)
return BAN::Error::from_errno(ETIMEDOUT);
Processor::pause(); Processor::pause();
}
// set bdl address, total size and lvi // set bdl address, total size and lvi
const paddr_t bdl_paddr = m_bdl_region->paddr() + bdl_offset(); const paddr_t bdl_paddr = m_bdl_region->paddr() + bdl_offset();
@@ -621,7 +632,13 @@ namespace Kernel
m_bdl_tail = (m_bdl_tail + 1) % m_bdl_entry_count; m_bdl_tail = (m_bdl_tail + 1) % m_bdl_entry_count;
if (m_bdl_tail == m_bdl_head) if (m_bdl_tail == m_bdl_head)
reset_stream(); {
if (auto ret = reset_stream(); ret.is_error())
{
dwarnln("failed to reset HDA stream: {}", ret.error());
return;
}
}
queue_bdl_data(); queue_bdl_data();
} }

View File

@@ -25,6 +25,7 @@ namespace Kernel
, m_attributes(attr) , m_attributes(attr)
, m_name(MUST(BAN::String::formatted("{}{}", name_prefix, index))) , m_name(MUST(BAN::String::formatted("{}{}", name_prefix, index)))
{ {
m_kind |= InodeKind::PARTITION;
m_rdev = makedev(major(device->rdev()), index); m_rdev = makedev(major(device->rdev()), index);
memcpy(m_label, label, sizeof(m_label)); memcpy(m_label, label, sizeof(m_label));
} }