diff --git a/kernel/include/kernel/Storage/ATAController.h b/kernel/include/kernel/Storage/ATAController.h index 81904ea0..0e3692d5 100644 --- a/kernel/include/kernel/Storage/ATAController.h +++ b/kernel/include/kernel/Storage/ATAController.h @@ -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 initialize(); + BAN::ErrorOr read(ATADevice*, uint64_t, uint8_t, uint8_t*); + private: + SpinLock m_lock; ATABus m_buses[2]; const PCIDevice& m_pci_device; + + friend class ATADevice; }; } \ No newline at end of file diff --git a/kernel/kernel/Storage/ATAController.cpp b/kernel/kernel/Storage/ATAController.cpp index fd199f29..12366a63 100644 --- a/kernel/kernel/Storage/ATAController.cpp +++ b/kernel/kernel/Storage/ATAController.cpp @@ -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 ATADevice::read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer) + BAN::ErrorOr 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 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)