The Pedigree Project 0.1
modules/drivers/common/nvme/main.cc
1/* Copyright (c) 2026, Pedigree Developers. SPDX-License-Identifier: ISC */
2#include "pedigree/kernel/ServiceManager.h"
3#include "pedigree/kernel/linker/KernelElf.h"
4#include "pedigree/kernel/machine/Disk.h"
5#include "pedigree/kernel/machine/PciDrivers.h"
6#include "pedigree/kernel/panic.h"
7#include "pedigree/kernel/utilities/new"
8
9#include "NvmeController.h"
10#include "modules/Module.h"
11namespace {
12Device* attach(Device* pci) {
13 auto* controller = new NvmeController(pci);
14 if (!controller) {
15 return nullptr;
16 }
17 if (!controller->initialiseController()) {
18 controller->shutdown();
19 delete controller;
20 return nullptr;
21 }
22 {
24 controller->setParent(pci);
25 pci->addChild(controller);
26 }
27 auto& services = ServiceManager::instance();
28 for (size_t i = 0; i < controller->getNumChildren(); ++i) {
29 auto* disk = static_cast<Disk*>(controller->getChild(i));
30 services.serve(String("partition"), ServiceFeatures::touch, disk, sizeof(disk));
31 }
32 return controller;
33}
34
35bool prepareRemove(Device* controller) {
36 return static_cast<NvmeController*>(controller)->prepareDiskRemoval();
37}
38
39void cancelRemove(Device* controller) {
40 static_cast<NvmeController*>(controller)->cancelDiskRemoval();
41}
42
43void remove(Device* device) {
44 auto* controller = static_cast<NvmeController*>(device);
45 controller->shutdown();
46 {
48 controller->getParent()->removeChild(controller);
49 controller->setParent(nullptr);
50 }
51 delete controller;
52}
53
54const PciDrivers::Driver driver{1, 8, 2, attach, prepareRemove, cancelRemove, remove};
55
56Module::UnloadAdmission admitUnload(bool) {
57 return PciDrivers::prepareUnregisterDriver(&driver) ? Module::UnloadAdmission::Ready
58 : Module::UnloadAdmission::Busy;
59}
60
61bool entry() {
62 if (!KernelElf::instance().registerUnloadAdmission(&entry, &admitUnload)) {
63 return false;
64 }
65 return PciDrivers::registerDriver(&driver);
66}
67
68void exit() {
69 if (!PciDrivers::unregisterDriver(&driver)) {
70 panic("NVMe: PCI driver registration still owns live bindings during unload");
71 }
72}
73} // namespace
74MODULE_INFO("nvme", &entry, &exit, "pci", "scsi");
void addChild(Device *pDevice)
Definition Device.cc:135
Device * getParent() const
Definition Device.h:166
void setParent(Device *p)
Definition Device.h:170
void removeChild(size_t n)
Definition Device.cc:147
Definition Disk.h:35
static KernelElf & instance()
Definition KernelElf.h:135
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
Definition panic.cc:118