drivers/nvdimm/virtio_pmem.c
Source file repositories/reference/linux-study-clean/drivers/nvdimm/virtio_pmem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvdimm/virtio_pmem.c- Extension
.c- Size
- 4727 bytes
- Lines
- 189
- Domain
- Driver Families
- Bucket
- drivers/nvdimm
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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
virtio_pmem.hnd.h
Detected Declarations
function init_vqfunction virtio_pmem_validatefunction virtio_pmem_probefunction virtio_pmem_removefunction virtio_pmem_freezefunction virtio_pmem_restore
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* virtio_pmem.c: Virtio pmem Driver
*
* Discovers persistent memory range information
* from host and registers the virtual pmem device
* with libnvdimm core.
*/
#include "virtio_pmem.h"
#include "nd.h"
static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_PMEM, VIRTIO_DEV_ANY_ID },
{ 0 },
};
/* Initialize virt queue */
static int init_vq(struct virtio_pmem *vpmem)
{
/* single vq */
vpmem->req_vq = virtio_find_single_vq(vpmem->vdev,
virtio_pmem_host_ack, "flush_queue");
if (IS_ERR(vpmem->req_vq))
return PTR_ERR(vpmem->req_vq);
spin_lock_init(&vpmem->pmem_lock);
INIT_LIST_HEAD(&vpmem->req_list);
return 0;
};
static int virtio_pmem_validate(struct virtio_device *vdev)
{
struct virtio_shm_region shm_reg;
if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION) &&
!virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID)
) {
dev_notice(&vdev->dev, "failed to get shared memory region %d\n",
VIRTIO_PMEM_SHMEM_REGION_ID);
__virtio_clear_bit(vdev, VIRTIO_PMEM_F_SHMEM_REGION);
}
return 0;
}
static int virtio_pmem_probe(struct virtio_device *vdev)
{
struct nd_region_desc ndr_desc = {};
struct nd_region *nd_region;
struct virtio_pmem *vpmem;
struct resource res;
struct virtio_shm_region shm_reg;
int err = 0;
if (!vdev->config->get) {
dev_err(&vdev->dev, "%s failure: config access disabled\n",
__func__);
return -EINVAL;
}
vpmem = devm_kzalloc(&vdev->dev, sizeof(*vpmem), GFP_KERNEL);
if (!vpmem) {
err = -ENOMEM;
goto out_err;
}
mutex_init(&vpmem->flush_lock);
vpmem->vdev = vdev;
vdev->priv = vpmem;
err = init_vq(vpmem);
if (err) {
dev_err(&vdev->dev, "failed to initialize virtio pmem vq's\n");
goto out_err;
}
if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION)) {
virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID);
vpmem->start = shm_reg.addr;
vpmem->size = shm_reg.len;
} else {
virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
start, &vpmem->start);
virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
size, &vpmem->size);
}
res.start = vpmem->start;
res.end = vpmem->start + vpmem->size - 1;
vpmem->nd_desc.provider_name = "virtio-pmem";
vpmem->nd_desc.module = THIS_MODULE;
Annotation
- Immediate include surface: `virtio_pmem.h`, `nd.h`.
- Detected declarations: `function init_vq`, `function virtio_pmem_validate`, `function virtio_pmem_probe`, `function virtio_pmem_remove`, `function virtio_pmem_freeze`, `function virtio_pmem_restore`.
- Atlas domain: Driver Families / drivers/nvdimm.
- Implementation status: source 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.