kernel+init: Create a device node in /dev to access the CDROM from userspace!
Some checks failed
continuous-integration/drone/pr Build is failing
Some checks failed
continuous-integration/drone/pr Build is failing
Still using PIO, though.
This commit is contained in:
parent
e18bca8c32
commit
0d1c01fd62
@ -4,6 +4,7 @@
|
|||||||
#include "arch/Timer.h"
|
#include "arch/Timer.h"
|
||||||
#include "arch/x86_64/IO.h"
|
#include "arch/x86_64/IO.h"
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
|
#include <luna/Alignment.h>
|
||||||
#include <luna/CType.h>
|
#include <luna/CType.h>
|
||||||
#include <luna/SafeArithmetic.h>
|
#include <luna/SafeArithmetic.h>
|
||||||
#include <luna/Vector.h>
|
#include <luna/Vector.h>
|
||||||
@ -329,6 +330,12 @@ namespace ATA
|
|||||||
m_drives[drive] = {};
|
m_drives[drive] = {};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ATADevice::create(m_drives[drive]).has_error())
|
||||||
|
{
|
||||||
|
kwarnln("ata: Failed to register ATA drive %d:%d in DeviceRegistry", m_channel_index, drive);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,6 +682,25 @@ namespace ATA
|
|||||||
return send_packet_atapi_pio(&read_packet, out, (u16)size);
|
return send_packet_atapi_pio(&read_packet, out, (u16)size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<void> Drive::read_lba(u64 lba, void* out, usize nblocks)
|
||||||
|
{
|
||||||
|
const usize blocks_per_page = ARCH_PAGE_SIZE / m_block_size;
|
||||||
|
if (m_is_atapi)
|
||||||
|
{
|
||||||
|
kdbgln("ata: Reading %zu blocks from ATAPI drive using PIO, at LBA %ld", nblocks, lba);
|
||||||
|
while (nblocks > blocks_per_page)
|
||||||
|
{
|
||||||
|
TRY(atapi_read_pio(lba, out, ARCH_PAGE_SIZE));
|
||||||
|
lba += blocks_per_page;
|
||||||
|
nblocks -= blocks_per_page;
|
||||||
|
out = offset_ptr(out, ARCH_PAGE_SIZE);
|
||||||
|
}
|
||||||
|
return atapi_read_pio(lba, out, nblocks * m_block_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
todo();
|
||||||
|
}
|
||||||
|
|
||||||
void Drive::irq_handler()
|
void Drive::irq_handler()
|
||||||
{
|
{
|
||||||
// Clear the IRQ flag.
|
// Clear the IRQ flag.
|
||||||
@ -694,3 +720,61 @@ namespace ATA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 next_minor = 0;
|
||||||
|
|
||||||
|
Result<void> ATADevice::create(SharedPtr<ATA::Drive> drive)
|
||||||
|
{
|
||||||
|
auto device = TRY(adopt_shared_if_nonnull(new (std::nothrow) ATADevice()));
|
||||||
|
device->m_drive = drive;
|
||||||
|
return DeviceRegistry::register_special_device(DeviceRegistry::Disk, next_minor++, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<u64> ATADevice::read(u8* buf, usize offset, usize size) const
|
||||||
|
{
|
||||||
|
if (size == 0) return 0;
|
||||||
|
|
||||||
|
if (offset > m_drive->capacity()) return 0;
|
||||||
|
if (offset + size > m_drive->capacity()) size = m_drive->capacity() - offset;
|
||||||
|
|
||||||
|
usize length = size;
|
||||||
|
|
||||||
|
auto block_size = m_drive->block_size();
|
||||||
|
|
||||||
|
auto* temp = TRY(make_array<u8>(block_size));
|
||||||
|
auto guard = make_scope_guard([temp] { delete[] temp; });
|
||||||
|
|
||||||
|
if (offset % block_size)
|
||||||
|
{
|
||||||
|
usize extra_size = block_size - (offset % block_size);
|
||||||
|
TRY(m_drive->read_lba(offset / block_size, temp, 1));
|
||||||
|
memcpy(buf, temp + (offset % block_size), extra_size);
|
||||||
|
offset += extra_size;
|
||||||
|
size -= extra_size;
|
||||||
|
buf += extra_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (size >= ARCH_PAGE_SIZE)
|
||||||
|
{
|
||||||
|
TRY(m_drive->read_lba(offset / block_size, buf, ARCH_PAGE_SIZE / block_size));
|
||||||
|
offset += ARCH_PAGE_SIZE;
|
||||||
|
size -= ARCH_PAGE_SIZE;
|
||||||
|
buf += ARCH_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (size >= block_size)
|
||||||
|
{
|
||||||
|
TRY(m_drive->read_lba(offset / block_size, buf, 1));
|
||||||
|
offset += block_size;
|
||||||
|
size -= block_size;
|
||||||
|
buf += block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
TRY(m_drive->read_lba(offset / block_size, temp, 1));
|
||||||
|
memcpy(buf, temp, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
@ -142,6 +142,23 @@ namespace ATA
|
|||||||
|
|
||||||
void irq_handler();
|
void irq_handler();
|
||||||
|
|
||||||
|
usize block_size() const
|
||||||
|
{
|
||||||
|
return m_block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize block_count() const
|
||||||
|
{
|
||||||
|
return m_block_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize capacity() const
|
||||||
|
{
|
||||||
|
return m_block_count * m_block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<void> read_lba(u64 lba, void* out, usize nblocks);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool identify_ata();
|
bool identify_ata();
|
||||||
|
|
||||||
@ -265,23 +282,28 @@ class ATADevice : public Device
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Initializer for DeviceRegistry.
|
// Initializer for DeviceRegistry.
|
||||||
static Result<void> create(SharedPtr<ATA::Controller> controller, int channel, int drive);
|
static Result<void> create(SharedPtr<ATA::Drive> drive);
|
||||||
|
|
||||||
Result<usize> read(u8*, usize, usize) const override;
|
Result<usize> read(u8*, usize, usize) const override;
|
||||||
|
|
||||||
Result<usize> write(const u8*, usize, usize) override;
|
Result<usize> write(const u8*, usize, usize) override
|
||||||
|
{
|
||||||
|
return err(ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
bool blocking() const override;
|
bool blocking() const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Result<u64> ioctl(int request, void* arg) override;
|
usize size() const override
|
||||||
|
{
|
||||||
usize size() const override;
|
return m_drive->capacity();
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~ATADevice() = default;
|
virtual ~ATADevice() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ATADevice(SharedPtr<ATA::Controller> controller);
|
ATADevice() = default;
|
||||||
SharedPtr<ATA::Controller> m_controller;
|
SharedPtr<ATA::Drive> m_drive;
|
||||||
int m_channel;
|
|
||||||
int m_drive;
|
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@ namespace DeviceRegistry
|
|||||||
Console = 1,
|
Console = 1,
|
||||||
Memory = 2,
|
Memory = 2,
|
||||||
Framebuffer = 3,
|
Framebuffer = 3,
|
||||||
|
Disk = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
Result<SharedPtr<Device>> fetch_special_device(u32 major, u32 minor);
|
Result<SharedPtr<Device>> fetch_special_device(u32 major, u32 minor);
|
||||||
|
Loading…
Reference in New Issue
Block a user