^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) static int devinfo_show(struct seq_file *f, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) int i = *(loff_t *) v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) if (i < CHRDEV_MAJOR_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) seq_puts(f, "Character devices:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) chrdev_show(f, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #ifdef CONFIG_BLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) i -= CHRDEV_MAJOR_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) seq_puts(f, "\nBlock devices:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) blkdev_show(f, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static void *devinfo_start(struct seq_file *f, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (*pos < (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) (*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (*pos >= (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static void devinfo_stop(struct seq_file *f, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static const struct seq_operations devinfo_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .start = devinfo_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .next = devinfo_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .stop = devinfo_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .show = devinfo_show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int __init proc_devices_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) proc_create_seq("devices", 0, NULL, &devinfo_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) fs_initcall(proc_devices_init);