From bfcf7ab3e85f9e4dd287fe449732532682f352d8 Mon Sep 17 00:00:00 2001 From: Pankaj Raghav Date: Sat, 29 Apr 2023 22:17:10 +0200 Subject: [PATCH] Kernel: Pass NVMeController reference to NVMequeue This is in preparation for adding MSI(x) support to the NVMe device. NVMeInterruptQueue needs access to the PCI device to deal with MSI(x) interrupts. It is ok to pass the NVMeController as a reference to the NVMeQueue as NVMeController is the one that owns the NVMeQueue. This is very similar to how AHCIController passes its reference to its interrupt handler. --- Kernel/Storage/NVMe/NVMeController.cpp | 4 ++-- Kernel/Storage/NVMe/NVMeInterruptQueue.cpp | 2 +- Kernel/Storage/NVMe/NVMeInterruptQueue.h | 2 +- Kernel/Storage/NVMe/NVMeQueue.cpp | 4 ++-- Kernel/Storage/NVMe/NVMeQueue.h | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Kernel/Storage/NVMe/NVMeController.cpp b/Kernel/Storage/NVMe/NVMeController.cpp index 27d2a135f0..b01591aad2 100644 --- a/Kernel/Storage/NVMe/NVMeController.cpp +++ b/Kernel/Storage/NVMe/NVMeController.cpp @@ -287,7 +287,7 @@ UNMAP_AFTER_INIT ErrorOr NVMeController::create_admin_queue(QueueType queu return maybe_error; } set_admin_queue_ready_flag(); - m_admin_queue = TRY(NVMeQueue::try_create(0, device_identifier().interrupt_line().value(), qdepth, move(cq_dma_region), cq_dma_pages, move(sq_dma_region), sq_dma_pages, move(doorbell_regs), queue_type)); + m_admin_queue = TRY(NVMeQueue::try_create(*this, 0, device_identifier().interrupt_line().value(), qdepth, move(cq_dma_region), cq_dma_pages, move(sq_dma_region), sq_dma_pages, move(doorbell_regs), queue_type)); dbgln_if(NVME_DEBUG, "NVMe: Admin queue created"); return {}; @@ -347,7 +347,7 @@ UNMAP_AFTER_INIT ErrorOr NVMeController::create_io_queue(u8 qid, QueueType auto queue_doorbell_offset = REG_SQ0TDBL_START + ((2 * qid) * (4 << m_dbl_stride)); auto doorbell_regs = TRY(Memory::map_typed_writable(PhysicalAddress(m_bar + queue_doorbell_offset))); - m_queues.append(TRY(NVMeQueue::try_create(qid, device_identifier().interrupt_line().value(), IO_QUEUE_SIZE, move(cq_dma_region), cq_dma_pages, move(sq_dma_region), sq_dma_pages, move(doorbell_regs), queue_type))); + m_queues.append(TRY(NVMeQueue::try_create(*this, qid, device_identifier().interrupt_line().value(), IO_QUEUE_SIZE, move(cq_dma_region), cq_dma_pages, move(sq_dma_region), sq_dma_pages, move(doorbell_regs), queue_type))); dbgln_if(NVME_DEBUG, "NVMe: Created IO Queue with QID{}", m_queues.size()); return {}; } diff --git a/Kernel/Storage/NVMe/NVMeInterruptQueue.cpp b/Kernel/Storage/NVMe/NVMeInterruptQueue.cpp index 68a77d962f..289b37b9c4 100644 --- a/Kernel/Storage/NVMe/NVMeInterruptQueue.cpp +++ b/Kernel/Storage/NVMe/NVMeInterruptQueue.cpp @@ -11,7 +11,7 @@ namespace Kernel { -UNMAP_AFTER_INIT NVMeInterruptQueue::NVMeInterruptQueue(NonnullOwnPtr rw_dma_region, Memory::PhysicalPage const& rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs) +UNMAP_AFTER_INIT NVMeInterruptQueue::NVMeInterruptQueue([[maybe_unused]] PCI::Device& device, NonnullOwnPtr rw_dma_region, Memory::PhysicalPage const& rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs) : NVMeQueue(move(rw_dma_region), rw_dma_page, qid, q_depth, move(cq_dma_region), cq_dma_page, move(sq_dma_region), sq_dma_page, move(db_regs)) , IRQHandler(irq) { diff --git a/Kernel/Storage/NVMe/NVMeInterruptQueue.h b/Kernel/Storage/NVMe/NVMeInterruptQueue.h index 79e401420f..c6e80603e8 100644 --- a/Kernel/Storage/NVMe/NVMeInterruptQueue.h +++ b/Kernel/Storage/NVMe/NVMeInterruptQueue.h @@ -13,7 +13,7 @@ namespace Kernel { class NVMeInterruptQueue : public NVMeQueue , public IRQHandler { public: - NVMeInterruptQueue(NonnullOwnPtr rw_dma_region, Memory::PhysicalPage const& rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs); + NVMeInterruptQueue(PCI::Device& device, NonnullOwnPtr rw_dma_region, Memory::PhysicalPage const& rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs); void submit_sqe(NVMeSubmission& submission) override; virtual ~NVMeInterruptQueue() override {}; diff --git a/Kernel/Storage/NVMe/NVMeQueue.cpp b/Kernel/Storage/NVMe/NVMeQueue.cpp index 415c003a86..0405a8fe86 100644 --- a/Kernel/Storage/NVMe/NVMeQueue.cpp +++ b/Kernel/Storage/NVMe/NVMeQueue.cpp @@ -12,7 +12,7 @@ #include namespace Kernel { -ErrorOr> NVMeQueue::try_create(u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs, QueueType queue_type) +ErrorOr> NVMeQueue::try_create(NVMeController& device, u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs, QueueType queue_type) { // Note: Allocate DMA region for RW operation. For now the requests don't exceed more than 4096 bytes (Storage device takes care of it) RefPtr rw_dma_page; @@ -21,7 +21,7 @@ ErrorOr> NVMeQueue::try_create(u16 qid, u8 irq, u32 auto queue = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) NVMePollQueue(move(rw_dma_region), *rw_dma_page, qid, q_depth, move(cq_dma_region), cq_dma_page, move(sq_dma_region), sq_dma_page, move(db_regs)))); return queue; } - auto queue = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) NVMeInterruptQueue(move(rw_dma_region), *rw_dma_page, qid, irq, q_depth, move(cq_dma_region), cq_dma_page, move(sq_dma_region), sq_dma_page, move(db_regs)))); + auto queue = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) NVMeInterruptQueue(device, move(rw_dma_region), *rw_dma_page, qid, irq, q_depth, move(cq_dma_region), cq_dma_page, move(sq_dma_region), sq_dma_page, move(db_regs)))); return queue; } diff --git a/Kernel/Storage/NVMe/NVMeQueue.h b/Kernel/Storage/NVMe/NVMeQueue.h index 006a926dd6..712fda1b78 100644 --- a/Kernel/Storage/NVMe/NVMeQueue.h +++ b/Kernel/Storage/NVMe/NVMeQueue.h @@ -39,9 +39,10 @@ struct NVMeIO { Function end_io_handler; }; +class NVMeController; class NVMeQueue : public AtomicRefCounted { public: - static ErrorOr> try_create(u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs, QueueType queue_type); + static ErrorOr> try_create(NVMeController& device, u16 qid, u8 irq, u32 q_depth, OwnPtr cq_dma_region, Vector> cq_dma_page, OwnPtr sq_dma_region, Vector> sq_dma_page, Memory::TypedMapping db_regs, QueueType queue_type); bool is_admin_queue() { return m_admin_queue; }; u16 submit_sync_sqe(NVMeSubmission&); void read(AsyncBlockDeviceRequest& request, u16 nsid, u64 index, u32 count);