drivers/staging/vme_user/vme_user.c
Source file repositories/reference/linux-study-clean/drivers/staging/vme_user/vme_user.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/staging/vme_user/vme_user.c- Extension
.c- Size
- 19854 bytes
- Lines
- 791
- Domain
- Driver Families
- Bucket
- drivers/staging
- 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/refcount.hlinux/cdev.hlinux/delay.hlinux/device.hlinux/dma-mapping.hlinux/errno.hlinux/init.hlinux/ioctl.hlinux/kernel.hlinux/mm.hlinux/module.hlinux/pagemap.hlinux/pci.hlinux/mutex.hlinux/slab.hlinux/spinlock.hlinux/syscalls.hlinux/types.hlinux/io.hlinux/uaccess.hvme.hvme_user.h
Detected Declarations
struct image_descstruct vme_user_vma_privfunction resource_to_userfunction resource_from_userfunction buffer_to_userfunction buffer_from_userfunction vme_user_readfunction vme_user_writefunction vme_user_llseekfunction methodfunction vme_user_unlocked_ioctlfunction vme_user_vm_openfunction vme_user_vm_closefunction vme_user_vm_mappedfunction vme_user_master_mmap_preparefunction vme_user_mmap_preparefunction vme_user_matchfunction vme_user_probefunction vme_user_removefunction vme_user_initfunction vme_user_exitmodule init vme_user_init
Annotated Snippet
static const struct file_operations vme_user_fops = {
.read = vme_user_read,
.write = vme_user_write,
.llseek = vme_user_llseek,
.unlocked_ioctl = vme_user_unlocked_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.mmap_prepare = vme_user_mmap_prepare,
};
static int vme_user_match(struct vme_dev *vdev)
{
int i;
int cur_bus = vme_bus_num(vdev);
int cur_slot = vme_slot_num(vdev);
for (i = 0; i < bus_num; i++)
if ((cur_bus == bus[i]) && (cur_slot == vdev->num))
return 1;
return 0;
}
/*
* In this simple access driver, the old behaviour is being preserved as much
* as practical. We will therefore reserve the buffers and request the images
* here so that we don't have to do it later.
*/
static int vme_user_probe(struct vme_dev *vdev)
{
int i, err;
char *name;
/* Save pointer to the bridge device */
if (vme_user_bridge) {
dev_err(&vdev->dev, "Driver can only be loaded for 1 device\n");
err = -EINVAL;
goto err_dev;
}
vme_user_bridge = vdev;
/* Initialise descriptors */
for (i = 0; i < VME_DEVS; i++) {
image[i].kern_buf = NULL;
image[i].pci_buf = 0;
mutex_init(&image[i].mutex);
image[i].device = NULL;
image[i].resource = NULL;
}
/* Assign major and minor numbers for the driver */
err = register_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS, DRIVER_NAME);
if (err) {
dev_warn(&vdev->dev, "Error getting Major Number %d for driver.\n",
VME_MAJOR);
goto err_region;
}
/* Register the driver as a char device */
vme_user_cdev = cdev_alloc();
if (!vme_user_cdev) {
err = -ENOMEM;
goto err_char;
}
vme_user_cdev->ops = &vme_user_fops;
vme_user_cdev->owner = THIS_MODULE;
err = cdev_add(vme_user_cdev, MKDEV(VME_MAJOR, 0), VME_DEVS);
if (err)
goto err_class;
/* Request slave resources and allocate buffers (128kB wide) */
for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
/* XXX Need to properly request attributes */
/* For ca91cx42 bridge there are only two slave windows
* supporting A16 addressing, so we request A24 supported
* by all windows.
*/
image[i].resource = vme_slave_request(vme_user_bridge,
VME_A24, VME_SCT);
if (!image[i].resource) {
dev_warn(&vdev->dev,
"Unable to allocate slave resource\n");
err = -ENOMEM;
goto err_slave;
}
image[i].size_buf = PCI_BUF_SIZE;
image[i].kern_buf = vme_alloc_consistent(image[i].resource,
image[i].size_buf,
&image[i].pci_buf);
if (!image[i].kern_buf) {
Annotation
- Immediate include surface: `linux/refcount.h`, `linux/cdev.h`, `linux/delay.h`, `linux/device.h`, `linux/dma-mapping.h`, `linux/errno.h`, `linux/init.h`, `linux/ioctl.h`.
- Detected declarations: `struct image_desc`, `struct vme_user_vma_priv`, `function resource_to_user`, `function resource_from_user`, `function buffer_to_user`, `function buffer_from_user`, `function vme_user_read`, `function vme_user_write`, `function vme_user_llseek`, `function method`.
- Atlas domain: Driver Families / drivers/staging.
- 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.