drivers/misc/mei/main.c
Source file repositories/reference/linux-study-clean/drivers/misc/mei/main.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/mei/main.c- Extension
.c- Size
- 30550 bytes
- Lines
- 1385
- Domain
- Driver Families
- Bucket
- drivers/misc
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/cleanup.hlinux/module.hlinux/moduleparam.hlinux/kernel.hlinux/device.hlinux/slab.hlinux/fs.hlinux/errno.hlinux/types.hlinux/fcntl.hlinux/pm_runtime.hlinux/poll.hlinux/init.hlinux/ioctl.hlinux/cdev.hlinux/sched/signal.hlinux/compat.hlinux/jiffies.hlinux/interrupt.hlinux/mei.hmei_dev.hclient.h
Detected Declarations
function mei_openfunction mei_cl_vtag_remove_by_fpfunction list_for_each_entry_safefunction mei_releasefunction mei_readfunction mei_cl_read_cbfunction mei_cl_vtag_by_fpfunction mei_writefunction mei_ioctl_connect_clientfunction mei_vt_support_checkfunction mei_ioctl_connect_vtagfunction list_for_each_entryfunction mei_ioctl_client_notify_requestfunction mei_ioctl_client_notify_getfunction mei_ioctlfunction mei_pollfunction mei_cl_is_write_queuedfunction mei_fsyncfunction mei_fasyncfunction trc_showfunction fw_status_showfunction hbm_ver_showfunction hbm_ver_drv_showfunction tx_queue_limit_showfunction tx_queue_limit_storefunction fw_ver_showfunction dev_state_showfunction mei_set_devstatefunction kind_showfunction mei_minor_getfunction mei_minor_freefunction mei_device_releasefunction mei_registerfunction mei_deregisterfunction mei_initfunction mei_exitmodule init mei_initexport mei_registerexport mei_deregister
Annotated Snippet
static const struct file_operations mei_fops = {
.owner = THIS_MODULE,
.read = mei_read,
.unlocked_ioctl = mei_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.open = mei_open,
.release = mei_release,
.write = mei_write,
.poll = mei_poll,
.fsync = mei_fsync,
.fasync = mei_fasync,
};
/**
* mei_minor_get - obtain next free device minor number
*
* @dev: device pointer
*
* Return: allocated minor, or -ENOSPC if no free minor left
*/
static int mei_minor_get(struct mei_device *dev)
{
int ret;
mutex_lock(&mei_minor_lock);
ret = idr_alloc(&mei_idr, dev, 0, MEI_MAX_DEVS, GFP_KERNEL);
if (ret >= 0)
dev->minor = ret;
else if (ret == -ENOSPC)
dev_err(&dev->dev, "too many mei devices\n");
mutex_unlock(&mei_minor_lock);
return ret;
}
/**
* mei_minor_free - mark device minor number as free
*
* @minor: minor number to free
*/
static void mei_minor_free(int minor)
{
mutex_lock(&mei_minor_lock);
idr_remove(&mei_idr, minor);
mutex_unlock(&mei_minor_lock);
}
static void mei_device_release(struct device *dev)
{
kfree(dev_get_drvdata(dev));
}
int mei_register(struct mei_device *dev, struct device *parent)
{
int ret, devno;
int minor;
ret = mei_minor_get(dev);
if (ret < 0)
return ret;
minor = dev->minor;
/* Fill in the data structures */
devno = MKDEV(MAJOR(mei_devt), dev->minor);
device_initialize(&dev->dev);
dev->dev.devt = devno;
dev->dev.class = &mei_class;
dev->dev.parent = parent;
dev->dev.groups = mei_groups;
dev->dev.release = mei_device_release;
dev_set_drvdata(&dev->dev, dev);
dev->cdev = cdev_alloc();
if (!dev->cdev) {
ret = -ENOMEM;
goto err;
}
dev->cdev->ops = &mei_fops;
dev->cdev->owner = parent->driver->owner;
cdev_set_parent(dev->cdev, &dev->dev.kobj);
/* Add the device */
ret = cdev_add(dev->cdev, devno, 1);
if (ret) {
dev_err(parent, "unable to add cdev for device %d:%d\n",
MAJOR(mei_devt), dev->minor);
goto err_del_cdev;
}
Annotation
- Immediate include surface: `linux/cleanup.h`, `linux/module.h`, `linux/moduleparam.h`, `linux/kernel.h`, `linux/device.h`, `linux/slab.h`, `linux/fs.h`, `linux/errno.h`.
- Detected declarations: `function mei_open`, `function mei_cl_vtag_remove_by_fp`, `function list_for_each_entry_safe`, `function mei_release`, `function mei_read`, `function mei_cl_read_cb`, `function mei_cl_vtag_by_fp`, `function mei_write`, `function mei_ioctl_connect_client`, `function mei_vt_support_check`.
- Atlas domain: Driver Families / drivers/misc.
- 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.