summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/CMakeLists.txt1
-rw-r--r--Kernel/Storage/ATA/ATADevice.cpp7
-rw-r--r--Kernel/Storage/NVMe/NVMeController.cpp6
-rw-r--r--Kernel/Storage/NVMe/NVMeController.h2
-rw-r--r--Kernel/Storage/NVMe/NVMeNameSpace.cpp9
-rw-r--r--Kernel/Storage/NVMe/NVMeNameSpace.h6
-rw-r--r--Kernel/Storage/Ramdisk/Device.cpp4
-rw-r--r--Kernel/Storage/StorageController.cpp17
-rw-r--r--Kernel/Storage/StorageController.h7
-rw-r--r--Kernel/Storage/StorageDevice.cpp3
-rw-r--r--Kernel/Storage/StorageDevice.h19
-rw-r--r--Kernel/Storage/StorageManagement.cpp8
-rw-r--r--Kernel/Storage/StorageManagement.h2
13 files changed, 76 insertions, 15 deletions
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt
index ca829adf64..f0a0cef579 100644
--- a/Kernel/CMakeLists.txt
+++ b/Kernel/CMakeLists.txt
@@ -116,6 +116,7 @@ set(KERNEL_SOURCES
Storage/NVMe/NVMeQueue.cpp
Storage/Ramdisk/Controller.cpp
Storage/Ramdisk/Device.cpp
+ Storage/StorageController.cpp
Storage/StorageDevice.cpp
Storage/StorageManagement.cpp
DoubleBuffer.cpp
diff --git a/Kernel/Storage/ATA/ATADevice.cpp b/Kernel/Storage/ATA/ATADevice.cpp
index b7c14f1d74..6acbaf7f08 100644
--- a/Kernel/Storage/ATA/ATADevice.cpp
+++ b/Kernel/Storage/ATA/ATADevice.cpp
@@ -13,8 +13,13 @@
namespace Kernel {
+static StorageDevice::LUNAddress convert_ata_address_to_lun_address(ATAController const& controller, ATADevice::Address ata_address)
+{
+ return StorageDevice::LUNAddress { controller.controller_id(), ata_address.port, ata_address.subport };
+}
+
ATADevice::ATADevice(ATAController const& controller, ATADevice::Address ata_address, MinorNumber minor_number, u16 capabilities, u16 logical_sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> early_storage_name)
- : StorageDevice(StorageManagement::storage_type_major_number(), minor_number, logical_sector_size, max_addressable_block, move(early_storage_name))
+ : StorageDevice(convert_ata_address_to_lun_address(controller, ata_address), StorageManagement::storage_type_major_number(), minor_number, logical_sector_size, max_addressable_block, move(early_storage_name))
, m_controller(controller)
, m_ata_address(ata_address)
, m_capabilities(capabilities)
diff --git a/Kernel/Storage/NVMe/NVMeController.cpp b/Kernel/Storage/NVMe/NVMeController.cpp
index 5744dee0f1..e60731bb44 100644
--- a/Kernel/Storage/NVMe/NVMeController.cpp
+++ b/Kernel/Storage/NVMe/NVMeController.cpp
@@ -19,13 +19,13 @@
#include <Kernel/Sections.h>
namespace Kernel {
-Atomic<u8> NVMeController::controller_id {};
+Atomic<u8> NVMeController::s_controller_id {};
UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NVMeController>> NVMeController::try_initialize(Kernel::PCI::DeviceIdentifier const& device_identifier, bool is_queue_polled)
{
auto controller = TRY(adopt_nonnull_ref_or_enomem(new NVMeController(device_identifier)));
TRY(controller->initialize(is_queue_polled));
- NVMeController::controller_id++;
+ NVMeController::s_controller_id++;
return controller;
}
@@ -207,7 +207,7 @@ UNMAP_AFTER_INIT ErrorOr<void> NVMeController::identify_and_init_namespaces()
dbgln_if(NVME_DEBUG, "NVMe: Block count is {} and Block size is {}", block_counts, block_size);
- m_namespaces.append(TRY(NVMeNameSpace::try_create(m_queues, controller_id.load(), nsid, block_counts, block_size)));
+ m_namespaces.append(TRY(NVMeNameSpace::try_create(*this, m_queues, s_controller_id.load(), nsid, block_counts, block_size)));
m_device_count++;
dbgln_if(NVME_DEBUG, "NVMe: Initialized namespace with NSID: {}", nsid);
}
diff --git a/Kernel/Storage/NVMe/NVMeController.h b/Kernel/Storage/NVMe/NVMeController.h
index 6f8615c0bb..198da902b1 100644
--- a/Kernel/Storage/NVMe/NVMeController.h
+++ b/Kernel/Storage/NVMe/NVMeController.h
@@ -77,6 +77,6 @@ private:
AK::Time m_ready_timeout;
u32 m_bar { 0 };
u8 m_dbl_stride { 0 };
- static Atomic<u8> controller_id;
+ static Atomic<u8> s_controller_id;
};
}
diff --git a/Kernel/Storage/NVMe/NVMeNameSpace.cpp b/Kernel/Storage/NVMe/NVMeNameSpace.cpp
index ec6e0cf95d..86f312784f 100644
--- a/Kernel/Storage/NVMe/NVMeNameSpace.cpp
+++ b/Kernel/Storage/NVMe/NVMeNameSpace.cpp
@@ -7,21 +7,22 @@
#include "NVMeNameSpace.h"
#include <AK/NonnullOwnPtr.h>
#include <Kernel/Devices/DeviceManagement.h>
+#include <Kernel/Storage/NVMe/NVMeController.h>
#include <Kernel/Storage/StorageManagement.h>
namespace Kernel {
-UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NVMeNameSpace>> NVMeNameSpace::try_create(NonnullRefPtrVector<NVMeQueue> queues, u8 controller_id, u16 nsid, size_t storage_size, size_t lba_size)
+UNMAP_AFTER_INIT ErrorOr<NonnullRefPtr<NVMeNameSpace>> NVMeNameSpace::try_create(NVMeController const& controller, NonnullRefPtrVector<NVMeQueue> queues, u8 controller_id, u16 nsid, size_t storage_size, size_t lba_size)
{
auto minor_number = StorageManagement::generate_storage_minor_number();
auto major_number = StorageManagement::storage_type_major_number();
auto device_name_kstring = TRY(KString::formatted("nvme{:d}n{:d}", controller_id, nsid));
- auto device = TRY(DeviceManagement::try_create_device<NVMeNameSpace>(move(queues), storage_size, lba_size, major_number.value(), minor_number.value(), nsid, move(device_name_kstring)));
+ auto device = TRY(DeviceManagement::try_create_device<NVMeNameSpace>(StorageDevice::LUNAddress { controller.controller_id(), nsid, 0 }, move(queues), storage_size, lba_size, major_number.value(), minor_number.value(), nsid, move(device_name_kstring)));
return device;
}
-UNMAP_AFTER_INIT NVMeNameSpace::NVMeNameSpace(NonnullRefPtrVector<NVMeQueue> queues, size_t max_addresable_block, size_t lba_size, size_t major_number, size_t minor_number, u16 nsid, NonnullOwnPtr<KString> dev_name)
- : StorageDevice(major_number, minor_number, lba_size, max_addresable_block, move(dev_name))
+UNMAP_AFTER_INIT NVMeNameSpace::NVMeNameSpace(LUNAddress logical_unit_number_address, NonnullRefPtrVector<NVMeQueue> queues, size_t max_addresable_block, size_t lba_size, size_t major_number, size_t minor_number, u16 nsid, NonnullOwnPtr<KString> dev_name)
+ : StorageDevice(logical_unit_number_address, major_number, minor_number, lba_size, max_addresable_block, move(dev_name))
, m_nsid(nsid)
, m_queues(move(queues))
{
diff --git a/Kernel/Storage/NVMe/NVMeNameSpace.h b/Kernel/Storage/NVMe/NVMeNameSpace.h
index e14a2b79df..6a1a1b10aa 100644
--- a/Kernel/Storage/NVMe/NVMeNameSpace.h
+++ b/Kernel/Storage/NVMe/NVMeNameSpace.h
@@ -19,17 +19,19 @@
#include <Kernel/Storage/StorageDevice.h>
namespace Kernel {
+
+class NVMeController;
class NVMeNameSpace : public StorageDevice {
friend class DeviceManagement;
public:
- static ErrorOr<NonnullRefPtr<NVMeNameSpace>> try_create(NonnullRefPtrVector<NVMeQueue> queues, u8 controller_id, u16 nsid, size_t storage_size, size_t lba_size);
+ static ErrorOr<NonnullRefPtr<NVMeNameSpace>> try_create(NVMeController const&, NonnullRefPtrVector<NVMeQueue> queues, u8 controller_id, u16 nsid, size_t storage_size, size_t lba_size);
CommandSet command_set() const override { return CommandSet::NVMe; };
void start_request(AsyncBlockDeviceRequest& request) override;
private:
- NVMeNameSpace(NonnullRefPtrVector<NVMeQueue> queues, size_t storage_size, size_t lba_size, size_t major_number, size_t minor_number, u16 nsid, NonnullOwnPtr<KString> early_device_name);
+ NVMeNameSpace(LUNAddress, NonnullRefPtrVector<NVMeQueue> queues, size_t storage_size, size_t lba_size, size_t major_number, size_t minor_number, u16 nsid, NonnullOwnPtr<KString> early_device_name);
virtual InterfaceType interface_type() const override { return InterfaceType::NVMe; }
u16 m_nsid;
diff --git a/Kernel/Storage/Ramdisk/Device.cpp b/Kernel/Storage/Ramdisk/Device.cpp
index 5d4689a359..ad173c4120 100644
--- a/Kernel/Storage/Ramdisk/Device.cpp
+++ b/Kernel/Storage/Ramdisk/Device.cpp
@@ -25,8 +25,8 @@ NonnullRefPtr<RamdiskDevice> RamdiskDevice::create(RamdiskController const& cont
return device_or_error.release_value();
}
-RamdiskDevice::RamdiskDevice(RamdiskController const&, NonnullOwnPtr<Memory::Region>&& region, int major, int minor, NonnullOwnPtr<KString> device_name)
- : StorageDevice(major, minor, 512, region->size() / 512, move(device_name))
+RamdiskDevice::RamdiskDevice(RamdiskController const& controller, NonnullOwnPtr<Memory::Region>&& region, int major, int minor, NonnullOwnPtr<KString> device_name)
+ : StorageDevice(LUNAddress { controller.controller_id(), 0, 0 }, major, minor, 512, region->size() / 512, move(device_name))
, m_region(move(region))
{
dmesgln("Ramdisk: Device #{} @ {}, Capacity={}", minor, m_region->vaddr(), max_addressable_block() * 512);
diff --git a/Kernel/Storage/StorageController.cpp b/Kernel/Storage/StorageController.cpp
new file mode 100644
index 0000000000..739c1ec1ae
--- /dev/null
+++ b/Kernel/Storage/StorageController.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <Kernel/Storage/StorageController.h>
+#include <Kernel/Storage/StorageManagement.h>
+
+namespace Kernel {
+
+StorageController::StorageController()
+ : m_controller_id(StorageManagement::generate_controller_id())
+{
+}
+
+}
diff --git a/Kernel/Storage/StorageController.h b/Kernel/Storage/StorageController.h
index e99674abdf..769441adda 100644
--- a/Kernel/Storage/StorageController.h
+++ b/Kernel/Storage/StorageController.h
@@ -29,10 +29,17 @@ public:
virtual RefPtr<StorageDevice> device(u32 index) const = 0;
virtual size_t devices_count() const = 0;
+ u32 controller_id() const { return m_controller_id; }
+
protected:
virtual bool reset() = 0;
virtual bool shutdown() = 0;
virtual void complete_current_request(AsyncDeviceRequest::RequestResult) = 0;
+
+ StorageController();
+
+private:
+ u32 const m_controller_id { 0 };
};
}
diff --git a/Kernel/Storage/StorageDevice.cpp b/Kernel/Storage/StorageDevice.cpp
index 6c8cc784cb..8ca455ea81 100644
--- a/Kernel/Storage/StorageDevice.cpp
+++ b/Kernel/Storage/StorageDevice.cpp
@@ -14,9 +14,10 @@
namespace Kernel {
-StorageDevice::StorageDevice(MajorNumber major, MinorNumber minor, size_t sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> device_name)
+StorageDevice::StorageDevice(LUNAddress logical_unit_number_address, MajorNumber major, MinorNumber minor, size_t sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> device_name)
: BlockDevice(major, minor, sector_size)
, m_early_storage_device_name(move(device_name))
+ , m_logical_unit_number_address(logical_unit_number_address)
, m_max_addressable_block(max_addressable_block)
, m_blocks_per_page(PAGE_SIZE / block_size())
{
diff --git a/Kernel/Storage/StorageDevice.h b/Kernel/Storage/StorageDevice.h
index a7747b1a11..eb06214a80 100644
--- a/Kernel/Storage/StorageDevice.h
+++ b/Kernel/Storage/StorageDevice.h
@@ -45,6 +45,20 @@ public:
NVMe,
};
+ // Note: The most reliable way to address this device from userspace interfaces,
+ // such as SysFS, is to have one way to enumerate everything in the eyes of userspace.
+ // Therefore, SCSI LUN (logical unit number) addressing seem to be the most generic way to do this.
+ // For example, on a legacy ATA instance, one might connect an harddrive to the second IDE controller,
+ // to the Primary channel as a slave device, which translates to LUN 1:0:1.
+ // On NVMe, for example, connecting a second PCIe NVMe storage device as a sole NVMe namespace translates
+ // to LUN 1:0:0.
+ // TODO: LUNs are also useful also when specifying the boot drive on boot. Consider doing that.
+ struct LUNAddress {
+ u32 controller_id;
+ u32 target_id;
+ u32 disk_id;
+ };
+
public:
virtual u64 max_addressable_block() const { return m_max_addressable_block; }
@@ -62,6 +76,8 @@ public:
void add_partition(NonnullRefPtr<DiskPartition> disk_partition) { MUST(m_partitions.try_append(disk_partition)); }
+ LUNAddress const& logical_unit_number_address() const { return m_logical_unit_number_address; }
+
virtual CommandSet command_set() const = 0;
StringView interface_type_to_string_view() const;
@@ -71,7 +87,7 @@ public:
virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) final;
protected:
- StorageDevice(MajorNumber, MinorNumber, size_t, u64, NonnullOwnPtr<KString>);
+ StorageDevice(LUNAddress, MajorNumber, MinorNumber, size_t, u64, NonnullOwnPtr<KString>);
// ^DiskDevice
virtual StringView class_name() const override;
@@ -82,6 +98,7 @@ private:
// FIXME: Remove this method after figuring out another scheme for naming.
NonnullOwnPtr<KString> m_early_storage_device_name;
+ LUNAddress const m_logical_unit_number_address;
u64 m_max_addressable_block { 0 };
size_t m_blocks_per_page { 0 };
};
diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp
index 2da6379b86..9f173ae864 100644
--- a/Kernel/Storage/StorageManagement.cpp
+++ b/Kernel/Storage/StorageManagement.cpp
@@ -30,6 +30,7 @@ namespace Kernel {
static Singleton<StorageManagement> s_the;
static Atomic<u32> s_device_minor_number;
+static Atomic<u32> s_controller_id;
static constexpr StringView partition_uuid_prefix = "PARTUUID:"sv;
@@ -244,6 +245,13 @@ MinorNumber StorageManagement::generate_storage_minor_number()
return minor_number;
}
+u32 StorageManagement::generate_controller_id()
+{
+ auto controller_id = s_controller_id.load();
+ s_controller_id++;
+ return controller_id;
+}
+
NonnullRefPtr<FileSystem> StorageManagement::root_filesystem() const
{
auto boot_device_description = boot_block_device();
diff --git a/Kernel/Storage/StorageManagement.h b/Kernel/Storage/StorageManagement.h
index 475a53540d..e4a85b59e3 100644
--- a/Kernel/Storage/StorageManagement.h
+++ b/Kernel/Storage/StorageManagement.h
@@ -31,6 +31,8 @@ public:
static MajorNumber storage_type_major_number();
static MinorNumber generate_storage_minor_number();
+ static u32 generate_controller_id();
+
void remove_device(StorageDevice&);
private: