drivers/vfio/fsl-mc/vfio_fsl_mc.c
Source file repositories/reference/linux-study-clean/drivers/vfio/fsl-mc/vfio_fsl_mc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/vfio/fsl-mc/vfio_fsl_mc.c- Extension
.c- Size
- 15726 bytes
- Lines
- 605
- Domain
- Driver Families
- Bucket
- drivers/vfio
- 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.
- 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/device.hlinux/iommu.hlinux/module.hlinux/mutex.hlinux/slab.hlinux/types.hlinux/vfio.hlinux/fsl/mc.hlinux/delay.hlinux/io-64-nonatomic-hi-lo.hvfio_fsl_mc_private.h
Detected Declarations
function vfio_fsl_mc_open_devicefunction vfio_fsl_mc_regions_cleanupfunction vfio_fsl_mc_reset_devicefunction vfio_fsl_mc_close_devicefunction vfio_fsl_mc_ioctl_get_region_infofunction vfio_fsl_mc_ioctlfunction vfio_fsl_mc_readfunction vfio_fsl_mc_send_commandfunction vfio_fsl_mc_writefunction vfio_fsl_mc_mmap_mmiofunction vfio_fsl_mc_mmapfunction vfio_fsl_mc_bus_notifierfunction vfio_fsl_mc_init_devicefunction vfio_fsl_mc_scan_containerfunction vfio_fsl_uninit_devicefunction vfio_fsl_mc_init_devfunction vfio_fsl_mc_probefunction vfio_fsl_mc_release_devfunction vfio_fsl_mc_remove
Annotated Snippet
if (ret) {
fsl_mc_obj_close(mc_dev->mc_io, 0, token);
goto out;
}
ret = fsl_mc_obj_close(mc_dev->mc_io, 0, token);
}
out:
return ret;
}
static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev)
{
struct vfio_fsl_mc_device *vdev =
container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
struct fsl_mc_device *mc_dev = vdev->mc_dev;
struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev);
struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev);
int ret;
vfio_fsl_mc_regions_cleanup(vdev);
/* reset the device before cleaning up the interrupts */
ret = vfio_fsl_mc_reset_device(vdev);
if (ret)
dev_warn(&mc_cont->dev,
"VFIO_FSL_MC: reset device has failed (%d)\n", ret);
vfio_fsl_mc_irqs_cleanup(vdev);
fsl_mc_cleanup_irq_pool(mc_cont);
}
static int vfio_fsl_mc_ioctl_get_region_info(struct vfio_device *core_vdev,
struct vfio_region_info *info,
struct vfio_info_cap *caps)
{
struct vfio_fsl_mc_device *vdev =
container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
struct fsl_mc_device *mc_dev = vdev->mc_dev;
if (info->index >= mc_dev->obj_desc.region_count)
return -EINVAL;
/* map offset to the physical address */
info->offset = VFIO_FSL_MC_INDEX_TO_OFFSET(info->index);
info->size = vdev->regions[info->index].size;
info->flags = vdev->regions[info->index].flags;
return 0;
}
static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev,
unsigned int cmd, unsigned long arg)
{
unsigned long minsz;
struct vfio_fsl_mc_device *vdev =
container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
struct fsl_mc_device *mc_dev = vdev->mc_dev;
switch (cmd) {
case VFIO_DEVICE_GET_INFO:
{
struct vfio_device_info info;
minsz = offsetofend(struct vfio_device_info, num_irqs);
if (copy_from_user(&info, (void __user *)arg, minsz))
return -EFAULT;
if (info.argsz < minsz)
return -EINVAL;
info.flags = VFIO_DEVICE_FLAGS_FSL_MC;
if (is_fsl_mc_bus_dprc(mc_dev))
info.flags |= VFIO_DEVICE_FLAGS_RESET;
info.num_regions = mc_dev->obj_desc.region_count;
info.num_irqs = mc_dev->obj_desc.irq_count;
return copy_to_user((void __user *)arg, &info, minsz) ?
-EFAULT : 0;
}
case VFIO_DEVICE_GET_IRQ_INFO:
{
struct vfio_irq_info info;
minsz = offsetofend(struct vfio_irq_info, count);
if (copy_from_user(&info, (void __user *)arg, minsz))
return -EFAULT;
Annotation
- Immediate include surface: `linux/device.h`, `linux/iommu.h`, `linux/module.h`, `linux/mutex.h`, `linux/slab.h`, `linux/types.h`, `linux/vfio.h`, `linux/fsl/mc.h`.
- Detected declarations: `function vfio_fsl_mc_open_device`, `function vfio_fsl_mc_regions_cleanup`, `function vfio_fsl_mc_reset_device`, `function vfio_fsl_mc_close_device`, `function vfio_fsl_mc_ioctl_get_region_info`, `function vfio_fsl_mc_ioctl`, `function vfio_fsl_mc_read`, `function vfio_fsl_mc_send_command`, `function vfio_fsl_mc_write`, `function vfio_fsl_mc_mmap_mmio`.
- Atlas domain: Driver Families / drivers/vfio.
- Implementation status: source 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.