drivers/input/mousedev.c
Source file repositories/reference/linux-study-clean/drivers/input/mousedev.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/mousedev.c- Extension
.c- Size
- 26214 bytes
- Lines
- 1126
- Domain
- Driver Families
- Bucket
- drivers/input
- 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/bitops.hlinux/sched.hlinux/slab.hlinux/poll.hlinux/module.hlinux/init.hlinux/input.hlinux/random.hlinux/major.hlinux/device.hlinux/cdev.hlinux/kernel.hlinux/miscdevice.h
Detected Declarations
struct mousedev_hw_datastruct mousedevstruct mousedev_motionstruct mousedev_clientenum mousedev_emulfunction mousedev_touchpad_eventfunction mousedev_abs_eventfunction mousedev_rel_eventfunction mousedev_key_eventfunction mousedev_notify_readersfunction mousedev_touchpad_touchfunction mousedev_eventfunction mousedev_fasyncfunction mousedev_freefunction mousedev_open_devicefunction mousedev_close_devicefunction mixdev_open_devicesfunction list_for_each_entryfunction mixdev_close_devicesfunction list_for_each_entryfunction mousedev_attach_clientfunction mousedev_detach_clientfunction mousedev_releasefunction mousedev_openfunction mousedev_packetfunction mousedev_generate_responsefunction mousedev_writefunction mousedev_readfunction mousedev_pollfunction mousedev_mark_deadfunction mousedev_hangupfunction mousedev_cleanupfunction mousedev_reserve_minorfunction mousedev_destroyfunction mixdev_add_devicefunction mixdev_remove_devicefunction mousedev_connectfunction mousedev_disconnectfunction mousedev_psaux_registerfunction mousedev_psaux_unregisterfunction mousedev_psaux_registerfunction mousedev_exitmodule init mousedev_init
Annotated Snippet
static const struct file_operations mousedev_fops = {
.owner = THIS_MODULE,
.read = mousedev_read,
.write = mousedev_write,
.poll = mousedev_poll,
.open = mousedev_open,
.release = mousedev_release,
.fasync = mousedev_fasync,
.llseek = noop_llseek,
};
/*
* Mark device non-existent. This disables writes, ioctls and
* prevents new users from opening the device. Already posted
* blocking reads will stay, however new ones will fail.
*/
static void mousedev_mark_dead(struct mousedev *mousedev)
{
mutex_lock(&mousedev->mutex);
mousedev->exist = false;
mutex_unlock(&mousedev->mutex);
}
/*
* Wake up users waiting for IO so they can disconnect from
* dead device.
*/
static void mousedev_hangup(struct mousedev *mousedev)
{
struct mousedev_client *client;
spin_lock(&mousedev->client_lock);
list_for_each_entry(client, &mousedev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
spin_unlock(&mousedev->client_lock);
wake_up_interruptible(&mousedev->wait);
}
static void mousedev_cleanup(struct mousedev *mousedev)
{
struct input_handle *handle = &mousedev->handle;
mousedev_mark_dead(mousedev);
mousedev_hangup(mousedev);
/* mousedev is marked dead so no one else accesses mousedev->open */
if (mousedev->open)
input_close_device(handle);
}
static int mousedev_reserve_minor(bool mixdev)
{
int minor;
if (mixdev) {
minor = input_get_new_minor(MOUSEDEV_MIX, 1, false);
if (minor < 0)
pr_err("failed to reserve mixdev minor: %d\n", minor);
} else {
minor = input_get_new_minor(MOUSEDEV_MINOR_BASE,
MOUSEDEV_MINORS, true);
if (minor < 0)
pr_err("failed to reserve new minor: %d\n", minor);
}
return minor;
}
static struct mousedev *mousedev_create(struct input_dev *dev,
struct input_handler *handler,
bool mixdev)
{
struct mousedev *mousedev;
int minor;
int error;
minor = mousedev_reserve_minor(mixdev);
if (minor < 0) {
error = minor;
goto err_out;
}
mousedev = kzalloc_obj(struct mousedev);
if (!mousedev) {
error = -ENOMEM;
goto err_free_minor;
}
INIT_LIST_HEAD(&mousedev->client_list);
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/sched.h`, `linux/slab.h`, `linux/poll.h`, `linux/module.h`, `linux/init.h`, `linux/input.h`, `linux/random.h`.
- Detected declarations: `struct mousedev_hw_data`, `struct mousedev`, `struct mousedev_motion`, `struct mousedev_client`, `enum mousedev_emul`, `function mousedev_touchpad_event`, `function mousedev_abs_event`, `function mousedev_rel_event`, `function mousedev_key_event`, `function mousedev_notify_readers`.
- Atlas domain: Driver Families / drivers/input.
- 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.