drivers/dax/bus.c
Source file repositories/reference/linux-study-clean/drivers/dax/bus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dax/bus.c- Extension
.c- Size
- 39361 bytes
- Lines
- 1626
- Domain
- Driver Families
- Bucket
- drivers/dax
- 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.
- 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/memremap.hlinux/device.hlinux/mutex.hlinux/list.hlinux/slab.hlinux/dax.hlinux/io.hdax-private.hbus.h
Detected Declarations
struct dax_idenum id_actionfunction dax_bus_ueventfunction dax_match_idfunction dax_match_typefunction do_id_storefunction new_id_storefunction remove_id_storefunction boundariesfunction static_dev_daxfunction dev_dax_sizefunction dax_bus_probefunction dax_bus_removefunction dax_bus_matchfunction id_showfunction region_size_showfunction region_align_showfunction dax_region_avail_sizefunction available_size_showfunction seed_showfunction create_showfunction create_storefunction kill_dev_daxfunction trim_dev_dax_rangefunction free_dev_dax_rangesfunction unregister_dev_daxfunction dax_region_freefunction dax_region_putfunction __free_dev_dax_idfunction free_dev_dax_idfunction alloc_dev_dax_idfunction delete_storefunction dax_region_visiblefunction dax_region_unregisterfunction dax_mapping_releasefunction unregister_dax_mappingfunction put_dax_rangefunction start_showfunction end_showfunction pgoff_showfunction devm_register_dax_mappingfunction alloc_dev_dax_rangefunction adjust_dev_dax_rangefunction size_showfunction alloc_is_alignedfunction dev_dax_shrinkfunction for_each_dax_region_resourcefunction adjust_ok
Annotated Snippet
static ssize_t do_id_store(struct device_driver *drv, const char *buf,
size_t count, enum id_action action)
{
struct dax_device_driver *dax_drv = to_dax_drv(drv);
unsigned int region_id, id;
char devname[DAX_NAME_LEN];
struct dax_id *dax_id;
ssize_t rc = count;
int fields;
fields = sscanf(buf, "dax%d.%d", ®ion_id, &id);
if (fields != 2)
return -EINVAL;
sprintf(devname, "dax%d.%d", region_id, id);
if (!sysfs_streq(buf, devname))
return -EINVAL;
mutex_lock(&dax_bus_lock);
dax_id = __dax_match_id(dax_drv, buf);
if (!dax_id) {
if (action == ID_ADD) {
dax_id = kzalloc_obj(*dax_id);
if (dax_id) {
strscpy(dax_id->dev_name, buf, DAX_NAME_LEN);
list_add(&dax_id->list, &dax_drv->ids);
} else
rc = -ENOMEM;
}
} else if (action == ID_REMOVE) {
list_del(&dax_id->list);
kfree(dax_id);
}
mutex_unlock(&dax_bus_lock);
if (rc < 0)
return rc;
if (action == ID_ADD)
rc = driver_attach(drv);
if (rc)
return rc;
return count;
}
static ssize_t new_id_store(struct device_driver *drv, const char *buf,
size_t count)
{
return do_id_store(drv, buf, count, ID_ADD);
}
static DRIVER_ATTR_WO(new_id);
static ssize_t remove_id_store(struct device_driver *drv, const char *buf,
size_t count)
{
return do_id_store(drv, buf, count, ID_REMOVE);
}
static DRIVER_ATTR_WO(remove_id);
static struct attribute *dax_drv_attrs[] = {
&driver_attr_new_id.attr,
&driver_attr_remove_id.attr,
NULL,
};
ATTRIBUTE_GROUPS(dax_drv);
static int dax_bus_match(struct device *dev, const struct device_driver *drv);
/*
* Static dax regions are regions created by an external subsystem
* nvdimm where a single range is assigned. Its boundaries are by the external
* subsystem and are usually limited to one physical memory range. For example,
* for PMEM it is usually defined by NVDIMM Namespace boundaries (i.e. a
* single contiguous range)
*
* On dynamic dax regions, the assigned region can be partitioned by dax core
* into multiple subdivisions. A subdivision is represented into one
* /dev/daxN.M device composed by one or more potentially discontiguous ranges.
*
* When allocating a dax region, drivers must set whether it's static
* (IORESOURCE_DAX_STATIC). On static dax devices, the @pgmap is pre-assigned
* to dax core when calling devm_create_dev_dax(), whereas in dynamic dax
* devices it is NULL but afterwards allocated by dax core on device ->probe().
* Care is needed to make sure that dynamic dax devices are torn down with a
* cleared @pgmap field (see kill_dev_dax()).
*/
static bool is_static(struct dax_region *dax_region)
{
return (dax_region->res.flags & IORESOURCE_DAX_STATIC) != 0;
}
bool static_dev_dax(struct dev_dax *dev_dax)
Annotation
- Immediate include surface: `linux/memremap.h`, `linux/device.h`, `linux/mutex.h`, `linux/list.h`, `linux/slab.h`, `linux/dax.h`, `linux/io.h`, `dax-private.h`.
- Detected declarations: `struct dax_id`, `enum id_action`, `function dax_bus_uevent`, `function dax_match_id`, `function dax_match_type`, `function do_id_store`, `function new_id_store`, `function remove_id_store`, `function boundaries`, `function static_dev_dax`.
- Atlas domain: Driver Families / drivers/dax.
- Implementation status: pattern implementation candidate.
- 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.