xref: /openbmc/linux/fs/proc/devices.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2fe251042SAlexey Dobriyan #include <linux/fs.h>
3fe251042SAlexey Dobriyan #include <linux/init.h>
4fe251042SAlexey Dobriyan #include <linux/proc_fs.h>
5fe251042SAlexey Dobriyan #include <linux/seq_file.h>
63f1266f1SChristoph Hellwig #include <linux/blkdev.h>
7*ef1d6178SAlexey Dobriyan #include "internal.h"
8fe251042SAlexey Dobriyan 
devinfo_show(struct seq_file * f,void * v)9fe251042SAlexey Dobriyan static int devinfo_show(struct seq_file *f, void *v)
10fe251042SAlexey Dobriyan {
11fe251042SAlexey Dobriyan 	int i = *(loff_t *) v;
12fe251042SAlexey Dobriyan 
138a932f73SLogan Gunthorpe 	if (i < CHRDEV_MAJOR_MAX) {
14fe251042SAlexey Dobriyan 		if (i == 0)
159d6de12fSAlexey Dobriyan 			seq_puts(f, "Character devices:\n");
16fe251042SAlexey Dobriyan 		chrdev_show(f, i);
17fe251042SAlexey Dobriyan 	}
18fe251042SAlexey Dobriyan #ifdef CONFIG_BLOCK
19fe251042SAlexey Dobriyan 	else {
208a932f73SLogan Gunthorpe 		i -= CHRDEV_MAJOR_MAX;
21fe251042SAlexey Dobriyan 		if (i == 0)
229d6de12fSAlexey Dobriyan 			seq_puts(f, "\nBlock devices:\n");
23fe251042SAlexey Dobriyan 		blkdev_show(f, i);
24fe251042SAlexey Dobriyan 	}
25fe251042SAlexey Dobriyan #endif
26fe251042SAlexey Dobriyan 	return 0;
27fe251042SAlexey Dobriyan }
28fe251042SAlexey Dobriyan 
devinfo_start(struct seq_file * f,loff_t * pos)29fe251042SAlexey Dobriyan static void *devinfo_start(struct seq_file *f, loff_t *pos)
30fe251042SAlexey Dobriyan {
31133d55cdSLogan Gunthorpe 	if (*pos < (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX))
32fe251042SAlexey Dobriyan 		return pos;
33fe251042SAlexey Dobriyan 	return NULL;
34fe251042SAlexey Dobriyan }
35fe251042SAlexey Dobriyan 
devinfo_next(struct seq_file * f,void * v,loff_t * pos)36fe251042SAlexey Dobriyan static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
37fe251042SAlexey Dobriyan {
38fe251042SAlexey Dobriyan 	(*pos)++;
39133d55cdSLogan Gunthorpe 	if (*pos >= (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX))
40fe251042SAlexey Dobriyan 		return NULL;
41fe251042SAlexey Dobriyan 	return pos;
42fe251042SAlexey Dobriyan }
43fe251042SAlexey Dobriyan 
devinfo_stop(struct seq_file * f,void * v)44fe251042SAlexey Dobriyan static void devinfo_stop(struct seq_file *f, void *v)
45fe251042SAlexey Dobriyan {
46fe251042SAlexey Dobriyan 	/* Nothing to do */
47fe251042SAlexey Dobriyan }
48fe251042SAlexey Dobriyan 
49fe251042SAlexey Dobriyan static const struct seq_operations devinfo_ops = {
50fe251042SAlexey Dobriyan 	.start = devinfo_start,
51fe251042SAlexey Dobriyan 	.next  = devinfo_next,
52fe251042SAlexey Dobriyan 	.stop  = devinfo_stop,
53fe251042SAlexey Dobriyan 	.show  = devinfo_show
54fe251042SAlexey Dobriyan };
55fe251042SAlexey Dobriyan 
proc_devices_init(void)56fe251042SAlexey Dobriyan static int __init proc_devices_init(void)
57fe251042SAlexey Dobriyan {
58*ef1d6178SAlexey Dobriyan 	struct proc_dir_entry *pde;
59*ef1d6178SAlexey Dobriyan 
60*ef1d6178SAlexey Dobriyan 	pde = proc_create_seq("devices", 0, NULL, &devinfo_ops);
61*ef1d6178SAlexey Dobriyan 	pde_make_permanent(pde);
62fe251042SAlexey Dobriyan 	return 0;
63fe251042SAlexey Dobriyan }
64abaf3787SPaul Gortmaker fs_initcall(proc_devices_init);
65