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