Kernel: ATA reads go through the ata controller and not only device

This commit is contained in:
Bananymous 2023-03-08 03:24:52 +02:00
parent 1dabe7a222
commit a068d828fe
2 changed files with 24 additions and 11 deletions

View File

@ -8,6 +8,7 @@ namespace Kernel
{
struct ATABus;
class ATAController;
class ATADevice : public StorageDevice
{
@ -34,7 +35,7 @@ namespace Kernel
char model[41];
ATABus* bus;
SpinLock m_lock;
ATAController* controller;
friend class ATAController;
};
@ -61,9 +62,14 @@ namespace Kernel
ATAController(const PCIDevice& device) : m_pci_device(device) {}
BAN::ErrorOr<void> initialize();
BAN::ErrorOr<void> read(ATADevice*, uint64_t, uint8_t, uint8_t*);
private:
SpinLock m_lock;
ATABus m_buses[2];
const PCIDevice& m_pci_device;
friend class ATADevice;
};
}

View File

@ -91,6 +91,7 @@ namespace Kernel
device.type = ATADevice::Type::Unknown;
device.slave_bit = device_index << 4;
device.bus = &bus;
device.controller = this;
bus.write(ATA_PORT_DRIVE_SELECT, 0xA0 | device.slave_bit);
PIT::sleep(1);
@ -183,9 +184,9 @@ namespace Kernel
return {};
}
BAN::ErrorOr<void> ATADevice::read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer)
BAN::ErrorOr<void> ATAController::read(ATADevice* device, uint64_t lba, uint8_t sector_count, uint8_t* buffer)
{
if (lba + sector_count > lba_count)
if (lba + sector_count > device->lba_count)
return BAN::Error::from_string("Attempted to read outside of the device boundaries");
LockGuard _(m_lock);
@ -193,17 +194,17 @@ namespace Kernel
if (lba < (1 << 28))
{
// LBA28
bus->write(ATA_PORT_DRIVE_SELECT, 0xE0 | slave_bit | ((lba >> 24) & 0x0F));
bus->write(ATA_PORT_SECTOR_COUNT, sector_count);
bus->write(ATA_PORT_LBA0, (uint8_t)(lba >> 0));
bus->write(ATA_PORT_LBA1, (uint8_t)(lba >> 8));
bus->write(ATA_PORT_LBA2, (uint8_t)(lba >> 16));
bus->write(ATA_PORT_COMMAND, ATA_COMMAND_READ_SECTORS);
device->bus->write(ATA_PORT_DRIVE_SELECT, 0xE0 | device->slave_bit | ((lba >> 24) & 0x0F));
device->bus->write(ATA_PORT_SECTOR_COUNT, sector_count);
device->bus->write(ATA_PORT_LBA0, (uint8_t)(lba >> 0));
device->bus->write(ATA_PORT_LBA1, (uint8_t)(lba >> 8));
device->bus->write(ATA_PORT_LBA2, (uint8_t)(lba >> 16));
device->bus->write(ATA_PORT_COMMAND, ATA_COMMAND_READ_SECTORS);
for (uint32_t sector = 0; sector < sector_count; sector++)
{
TRY(bus->wait(true));
bus->read_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * sector_words, sector_words);
TRY(device->bus->wait(true));
device->bus->read_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * device->sector_words, device->sector_words);
}
}
else
@ -215,6 +216,12 @@ namespace Kernel
return {};
}
BAN::ErrorOr<void> ATADevice::read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer)
{
TRY(controller->read(this, lba, sector_count, buffer));
return {};
}
uint8_t ATABus::read(uint16_t port)
{
if (port <= 0x07)