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

View File

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