diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index f83427b349504a62d854d93b60ca94c4ca79dd0b..92167d0ecb5f9217153d79a5d9776f16aea90c7e 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -424,13 +424,6 @@ static int filesystems_read_proc(char *page, char **start, off_t off, return proc_calc_metrics(page, start, off, count, eof, len); } -static int ioports_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = get_ioport_list(page); - return proc_calc_metrics(page, start, off, count, eof, len); -} - static int cmdline_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -469,13 +462,6 @@ static int execdomains_read_proc(char *page, char **start, off_t off, return proc_calc_metrics(page, start, off, count, eof, len); } -static int memory_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = get_mem_list(page); - return proc_calc_metrics(page, start, off, count, eof, len); -} - /* * This function accesses profiling information. The returned data is * binary: the sampling step and the actual contents of the profile @@ -569,13 +555,11 @@ void __init proc_misc_init(void) {"stat", kstat_read_proc}, {"devices", devices_read_proc}, {"filesystems", filesystems_read_proc}, - {"ioports", ioports_read_proc}, {"cmdline", cmdline_read_proc}, #ifdef CONFIG_SGI_DS1286 {"rtc", ds1286_read_proc}, #endif {"locks", locks_read_proc}, - {"iomem", memory_read_proc}, {"execdomains", execdomains_read_proc}, {NULL,} }; diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 7a9431f4673f3bb9ed870eb239c7c2734b8d4210..6730ec8233218be93a00cb08c2763feb44e57c0a 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -112,7 +112,4 @@ extern struct resource * __request_region(struct resource *, unsigned long start extern int __deprecated __check_region(struct resource *, unsigned long, unsigned long); extern void __release_region(struct resource *, unsigned long, unsigned long); -#define get_ioport_list(buf) get_resource_list(&ioport_resource, buf, PAGE_SIZE) -#define get_mem_list(buf) get_resource_list(&iomem_resource, buf, PAGE_SIZE) - #endif /* _LINUX_IOPORT_H */ diff --git a/kernel/resource.c b/kernel/resource.c index 83d04826245dba403fd9335d7744231d88f8e864..ca82abf27fc9376b1732c71130a5ae1d5a78ceba 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -7,61 +7,125 @@ * Arbitrary resource management. */ +#include <linux/config.h> #include <linux/sched.h> #include <linux/errno.h> #include <linux/ioport.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/fs.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <asm/io.h> + struct resource ioport_resource = { "PCI IO", 0x0000, IO_SPACE_LIMIT, IORESOURCE_IO }; struct resource iomem_resource = { "PCI mem", 0x00000000, 0xffffffff, IORESOURCE_MEM }; static rwlock_t resource_lock = RW_LOCK_UNLOCKED; +#ifdef CONFIG_PROC_FS + +#define MAX_IORES_LEVEL 5 + /* - * This generates reports for /proc/ioports and /proc/iomem + * do_resource_list(): + * for reports of /proc/ioports and /proc/iomem; + * do current entry, then children, then siblings; */ -static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end) +static int do_resource_list(struct seq_file *m, struct resource *res, const char *fmt, int level) { - if (offset < 0) - offset = 0; + while (res) { + const char *name; - while (entry) { - const char *name = entry->name; - unsigned long from, to; + name = res->name ? res->name : "<BAD>"; + if (level > MAX_IORES_LEVEL) + level = MAX_IORES_LEVEL; + seq_printf (m, fmt + 2 * MAX_IORES_LEVEL - 2 * level, + res->start, res->end, name); - if ((int) (end-buf) < 80) - return buf; + if (res->child) + do_resource_list(m, res->child, fmt, level + 1); - from = entry->start; - to = entry->end; - if (!name) - name = "<BAD>"; - - buf += sprintf(buf, fmt + offset, from, to, name); - if (entry->child) - buf = do_resource_list(entry->child, fmt, offset-2, buf, end); - entry = entry->sibling; + res = res->sibling; } - return buf; + return 0; } -int get_resource_list(struct resource *root, char *buf, int size) +static int ioresources_show(struct seq_file *m, void *v) { + struct resource *root = m->private; char *fmt; int retval; - fmt = " %08lx-%08lx : %s\n"; - if (root->end < 0x10000) - fmt = " %04lx-%04lx : %s\n"; + fmt = root->end < 0x10000 + ? " %04lx-%04lx : %s\n" + : " %08lx-%08lx : %s\n"; read_lock(&resource_lock); - retval = do_resource_list(root->child, fmt, 8, buf, buf + size) - buf; + retval = do_resource_list(m, root->child, fmt, 0); read_unlock(&resource_lock); return retval; -} +} + +static int ioresources_open(struct file *file, struct resource *root) +{ + char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + struct seq_file *m; + int res; + + if (!buf) + return -ENOMEM; + res = single_open(file, ioresources_show, root); + if (!res) { + m = file->private_data; + m->buf = buf; + m->size = PAGE_SIZE; + } else + kfree(buf); + return res; +} + +static int ioports_open(struct inode *inode, struct file *file) +{ + return ioresources_open(file, &ioport_resource); +} + +static struct file_operations proc_ioports_operations = { + .open = ioports_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int iomem_open(struct inode *inode, struct file *file) +{ + return ioresources_open(file, &iomem_resource); +} + +static struct file_operations proc_iomem_operations = { + .open = iomem_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init ioresources_init(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_entry("ioports", 0, NULL); + if (entry) + entry->proc_fops = &proc_ioports_operations; + entry = create_proc_entry("iomem", 0, NULL); + if (entry) + entry->proc_fops = &proc_iomem_operations; + return 0; +} +__initcall(ioresources_init); + +#endif /* CONFIG_PROC_FS */ /* Return the conflict entry if you can't request it */ static struct resource * __request_resource(struct resource *root, struct resource *new)