drivers/nvdimm/bus.c
Source file repositories/reference/linux-study-clean/drivers/nvdimm/bus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvdimm/bus.c- Extension
.c- Size
- 31893 bytes
- Lines
- 1334
- Domain
- Driver Families
- Bucket
- drivers/nvdimm
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/libnvdimm.hlinux/sched/mm.hlinux/slab.hlinux/uaccess.hlinux/module.hlinux/blkdev.hlinux/fcntl.hlinux/async.hlinux/ndctl.hlinux/sched.hlinux/cpu.hlinux/fs.hlinux/io.hlinux/mm.hlinux/nd.hnd-core.hnd.hpfn.h
Detected Declarations
struct clear_badblocks_contextenum nd_ioctl_modefunction to_nd_device_typefunction nvdimm_bus_ueventfunction nvdimm_bus_probe_startfunction nvdimm_bus_probe_endfunction nvdimm_bus_probefunction nvdimm_bus_removefunction nvdimm_bus_shutdownfunction nd_device_notifyfunction nvdimm_region_notifyfunction nvdimm_clear_badblocks_regionfunction nvdimm_clear_badblocks_regionsfunction nvdimm_account_cleared_poisonfunction nvdimm_clear_poisonfunction nvdimm_bus_releasefunction is_nvdimm_busfunction nvdimm_bus_unregisterfunction child_unregisterfunction free_badrange_listfunction list_for_each_entry_safefunction nd_bus_removefunction nd_bus_probefunction nvdimm_bus_matchfunction nd_synchronizefunction nd_async_device_registerfunction nd_async_device_unregisterfunction __nd_device_registerfunction nd_device_registerfunction nd_device_register_syncfunction nd_device_unregisterfunction __nd_driver_registerfunction nvdimm_check_and_set_rofunction modalias_showfunction devtype_showfunction numa_node_showfunction nvdimm_dev_to_target_nodefunction target_node_showfunction nd_numa_attr_visiblefunction ndctl_releasefunction nvdimm_bus_create_ndctlfunction nvdimm_bus_destroy_ndctlfunction nd_cmd_in_sizefunction nd_cmd_out_sizefunction wait_nvdimm_bus_probe_idlefunction nd_pmem_forget_poison_checkfunction nd_ns_forget_poison_checkfunction nd_cmd_clear_to_send
Annotated Snippet
static int nvdimm_bus_match(struct device *dev, const struct device_driver *drv);
static const struct bus_type nvdimm_bus_type = {
.name = "nd",
.uevent = nvdimm_bus_uevent,
.match = nvdimm_bus_match,
.probe = nvdimm_bus_probe,
.remove = nvdimm_bus_remove,
.shutdown = nvdimm_bus_shutdown,
};
static void nvdimm_bus_release(struct device *dev)
{
struct nvdimm_bus *nvdimm_bus;
nvdimm_bus = container_of(dev, struct nvdimm_bus, dev);
ida_free(&nd_ida, nvdimm_bus->id);
kfree(nvdimm_bus);
}
static const struct device_type nvdimm_bus_dev_type = {
.release = nvdimm_bus_release,
.groups = nvdimm_bus_attribute_groups,
};
bool is_nvdimm_bus(struct device *dev)
{
return dev->type == &nvdimm_bus_dev_type;
}
struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev)
{
struct device *dev;
for (dev = nd_dev; dev; dev = dev->parent)
if (is_nvdimm_bus(dev))
break;
dev_WARN_ONCE(nd_dev, !dev, "invalid dev, not on nd bus\n");
if (dev)
return to_nvdimm_bus(dev);
return NULL;
}
struct nvdimm_bus *to_nvdimm_bus(struct device *dev)
{
struct nvdimm_bus *nvdimm_bus;
nvdimm_bus = container_of(dev, struct nvdimm_bus, dev);
WARN_ON(!is_nvdimm_bus(dev));
return nvdimm_bus;
}
EXPORT_SYMBOL_GPL(to_nvdimm_bus);
struct nvdimm_bus *nvdimm_to_bus(struct nvdimm *nvdimm)
{
return to_nvdimm_bus(nvdimm->dev.parent);
}
EXPORT_SYMBOL_GPL(nvdimm_to_bus);
static struct lock_class_key nvdimm_bus_key;
struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
struct nvdimm_bus_descriptor *nd_desc)
{
struct nvdimm_bus *nvdimm_bus;
int rc;
nvdimm_bus = kzalloc_obj(*nvdimm_bus);
if (!nvdimm_bus)
return NULL;
INIT_LIST_HEAD(&nvdimm_bus->list);
INIT_LIST_HEAD(&nvdimm_bus->mapping_list);
init_waitqueue_head(&nvdimm_bus->wait);
nvdimm_bus->id = ida_alloc(&nd_ida, GFP_KERNEL);
if (nvdimm_bus->id < 0) {
kfree(nvdimm_bus);
return NULL;
}
mutex_init(&nvdimm_bus->reconfig_mutex);
badrange_init(&nvdimm_bus->badrange);
nvdimm_bus->nd_desc = nd_desc;
nvdimm_bus->dev.parent = parent;
nvdimm_bus->dev.type = &nvdimm_bus_dev_type;
nvdimm_bus->dev.groups = nd_desc->attr_groups;
nvdimm_bus->dev.bus = &nvdimm_bus_type;
nvdimm_bus->dev.of_node = nd_desc->of_node;
device_initialize(&nvdimm_bus->dev);
lockdep_set_class(&nvdimm_bus->dev.mutex, &nvdimm_bus_key);
device_set_pm_not_required(&nvdimm_bus->dev);
rc = dev_set_name(&nvdimm_bus->dev, "ndbus%d", nvdimm_bus->id);
Annotation
- Immediate include surface: `linux/libnvdimm.h`, `linux/sched/mm.h`, `linux/slab.h`, `linux/uaccess.h`, `linux/module.h`, `linux/blkdev.h`, `linux/fcntl.h`, `linux/async.h`.
- Detected declarations: `struct clear_badblocks_context`, `enum nd_ioctl_mode`, `function to_nd_device_type`, `function nvdimm_bus_uevent`, `function nvdimm_bus_probe_start`, `function nvdimm_bus_probe_end`, `function nvdimm_bus_probe`, `function nvdimm_bus_remove`, `function nvdimm_bus_shutdown`, `function nd_device_notify`.
- Atlas domain: Driver Families / drivers/nvdimm.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.