// SPDX-License-Identifier: GPL-2.0 /* * linux/drivers/char/misc.c * * Generic misc open routine by Johan Myreen * * Based on code from Linus * * Teemu Rantanen's Microsoft Busmouse support and Derrick Cole's * changes incorporated into 0.97pl4 * by Peter Cervasio (pete%[email protected]) (08SEP92) * See busmouse.c for particulars. * * Made things a lot mode modular - easy to compile in just one or two * of the misc drivers, as they are now completely independent. Linus. * * Support for loadable modules. 8-Sep-95 Philip Blundell <[email protected]> * * Fixed a failing symbol register to free the device registration * Alan Cox <[email protected]> 21-Jan-96 * * Dynamic minors and /proc/mice by Alessandro Rubini. 26-Mar-96 * * Renamed to misc and miscdevice to be more accurate. Alan Cox 26-Mar-96 * * Handling of mouse minor numbers for kerneld: * Idea by Jacques Gelinas <[email protected]>, * adapted by Bjorn Ekwall <[email protected]> * corrected by Alan Cox <[email protected]> * * Changes for kmod (from kerneld): * Cyrus Durgin <[email protected]> * * Added devfs support. Richard Gooch <[email protected]> 10-Jan-1998 */ #include <linux/module.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/miscdevice.h> #include <linux/kernel.h> #include <linux/major.h> #include <linux/mutex.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/stat.h> #include <linux/init.h> #include <linux/device.h> #include <linux/tty.h> #include <linux/kmod.h> #include <linux/gfp.h> /* * Head entry for the doubly linked miscdevice list */ static LIST_HEAD(misc_list); static DEFINE_MUTEX(misc_mtx); /* * Assigned numbers, used for dynamic minors */ #define DYNAMIC_MINORS … static DEFINE_IDA(misc_minors_ida); static int misc_minor_alloc(void) { … } static void misc_minor_free(int minor) { … } #ifdef CONFIG_PROC_FS static void *misc_seq_start(struct seq_file *seq, loff_t *pos) { … } static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos) { … } static void misc_seq_stop(struct seq_file *seq, void *v) { … } static int misc_seq_show(struct seq_file *seq, void *v) { … } static const struct seq_operations misc_seq_ops = …; #endif static int misc_open(struct inode *inode, struct file *file) { … } static char *misc_devnode(const struct device *dev, umode_t *mode) { … } static const struct class misc_class = …; static const struct file_operations misc_fops = …; /** * misc_register - register a miscellaneous device * @misc: device structure * * Register a miscellaneous device with the kernel. If the minor * number is set to %MISC_DYNAMIC_MINOR a minor number is assigned * and placed in the minor field of the structure. For other cases * the minor number requested is used. * * The structure passed is linked into the kernel and may not be * destroyed until it has been unregistered. By default, an open() * syscall to the device sets file->private_data to point to the * structure. Drivers don't need open in fops for this. * * A zero is returned on success and a negative errno code for * failure. */ int misc_register(struct miscdevice *misc) { … } EXPORT_SYMBOL(…); /** * misc_deregister - unregister a miscellaneous device * @misc: device to unregister * * Unregister a miscellaneous device that was previously * successfully registered with misc_register(). */ void misc_deregister(struct miscdevice *misc) { … } EXPORT_SYMBOL(…); static int __init misc_init(void) { … } subsys_initcall(misc_init);