1 #include <linux/fs.h> 2 #include <linux/init.h> 3 #include <linux/proc_fs.h> 4 #include <linux/seq_file.h> 5 6 static int devinfo_show(struct seq_file *f, void *v) 7 { 8 int i = *(loff_t *) v; 9 10 if (i < CHRDEV_MAJOR_MAX) { 11 if (i == 0) 12 seq_puts(f, "Character devices:\n"); 13 chrdev_show(f, i); 14 } 15 #ifdef CONFIG_BLOCK 16 else { 17 i -= CHRDEV_MAJOR_MAX; 18 if (i == 0) 19 seq_puts(f, "\nBlock devices:\n"); 20 blkdev_show(f, i); 21 } 22 #endif 23 return 0; 24 } 25 26 static void *devinfo_start(struct seq_file *f, loff_t *pos) 27 { 28 if (*pos < (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX)) 29 return pos; 30 return NULL; 31 } 32 33 static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) 34 { 35 (*pos)++; 36 if (*pos >= (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX)) 37 return NULL; 38 return pos; 39 } 40 41 static void devinfo_stop(struct seq_file *f, void *v) 42 { 43 /* Nothing to do */ 44 } 45 46 static const struct seq_operations devinfo_ops = { 47 .start = devinfo_start, 48 .next = devinfo_next, 49 .stop = devinfo_stop, 50 .show = devinfo_show 51 }; 52 53 static int devinfo_open(struct inode *inode, struct file *filp) 54 { 55 return seq_open(filp, &devinfo_ops); 56 } 57 58 static const struct file_operations proc_devinfo_operations = { 59 .open = devinfo_open, 60 .read = seq_read, 61 .llseek = seq_lseek, 62 .release = seq_release, 63 }; 64 65 static int __init proc_devices_init(void) 66 { 67 proc_create("devices", 0, NULL, &proc_devinfo_operations); 68 return 0; 69 } 70 fs_initcall(proc_devices_init); 71