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